Ok here is a very rough draft, its very late here, and Im going to sleep. I will make improvements tomorrows, mainly adding comments etc. Its made according to outline from my previous post.
It turned out quite different from the original code, mainly due to me preferring the ArrayList class to the fixed array structure.
public class driver {
public static void main(String[] args) {
Game game = new Game();
game.start();
}
}
public class Game {
private Gameboard gb;
private GameLogic gl;
public Game(){
gb = new Gameboard();
gl = new GameLogic(gb);
}
/**
* Starts the game. Runs the flow of the game.
*/
public void start(){
//Start promt
System.out.println("Welcome to tic-tac-toe");
System.out.println("You will be playing X, the computer will be playing O\n");
while (gl.checkGameStatus()){
gb.printAvailSpace();
gl.takePlayerTurn();
gb.printGameBoard();
gl.takeCPUturn();
gb.printGameBoard();
}
}
}
import java.util.ArrayList;
public class Gameboard {
private ArrayList<Tile> boardList = new ArrayList<Tile>();
public Gameboard(){
//Initializing the gameboard
for (int i = 0; i < 10; i++) {
boardList.add(i, new Tile());
}
}
/**
* Prints the board using the overridden toString in Tile.
*/
public void printGameBoard() {
System.out.println(boardList.get(0).toString() + " " + boardList.get(1).toString() + " " + boardList.get(2).toString()); // game board logic
System.out.println(boardList.get(3).toString() + " " + boardList.get(4).toString() + " " + boardList.get(5).toString()); // prints values if space is entered,
System.out.println(boardList.get(6).toString() + " " + boardList.get(7).toString() + " " + boardList.get(8).toString()); // else prints "-"
System.out.println();
}
/**
* display available space
*/
public void printAvailSpace() {
System.out.print("Available empty spaces: ");
for (int i = 0; i < 8; i++) {
if (boardList.get(i).toString().equals("-")) System.out.print( i + ", ");
else System.out.print("");
}
if (boardList.get(8).toString().equals("-")) System.out.println(8);
}
/**
* Check if a tile is already occupied by either Player or CPU
* @param space
* @return
*/
public boolean isAvail(int space){
if (boardList.get(space).isOwnedByCPU || boardList.get(space).isOwnedByPlayer){
return false;
}
else return true;
}
public void setOwnedPlayer(int pos){
boardList.get(pos).setOwnedByPlayer();
}
public void setOwnedCPU(int pos){
boardList.get(pos).setOwnedByCPU();
}
/**
* returns an int value according to the owner of the tile.
* Used for checking for 3 in a line.
* 0 for cpu
* 1 for player
* @param space
* @return
*/
public int getOwner(int pos){
if (boardList.get(pos).isOwnedByCPU) return 0;
else if (boardList.get(pos).isOwnedByPlayer) return 1;
else return 2;
}
}
import java.util.Random;
import java.util.Scanner;
public class GameLogic {
private Scanner scan = new Scanner(System.in);
private Gameboard gb = new Gameboard();
private Random r = new Random();
private int totalTurns;
public GameLogic(Gameboard gameboard){
gb = gameboard;
totalTurns = 0;
}
/**
* Handling the player move.
* The player enters an int in the console.
* The int is inserted to the gameboard if not occupied.
*/
public void takePlayerTurn () {
System.out.println("select you space ");
int x = scan.nextInt();
if (gb.isAvail(x)){
gb.setOwnedPlayer(x);
totalTurns++;
}
else takePlayerTurn ();
}
/**
* Handling the CPU turn.
* CPU selects a random int between 0-9.
* If occupied, the method is recursivly called again.
*/
public void takeCPUturn(){
System.out.println("CPU is trying to make a move");
int x = r.nextInt(9);
if (gb.isAvail(x)){
gb.setOwnedCPU(x);
totalTurns++;
}
else if (totalTurns > 8) System.out.println("Cpu cant move, no available space");
else takeCPUturn();
}
/**
* Checks weather the game has ended, either by finding a winner
* or by all tiles being taken.
* @return
*/
public boolean checkGameStatus(){
//checking for 3 in a row
for (int i = 0; i < 7; i = i + 3){
if (gb.getOwner(i) != 2 && gb.getOwner(i) == gb.getOwner(i+1) && gb.getOwner(i+1) == gb.getOwner(i+2)){
if (gb.getOwner(i) == 0) System.out.println("CPU wins");
else System.out.println("Player wins");
return false;
}
}
//checking for 3 in a column
for (int j = 0; j < 3; j = j + 1){
if (gb.getOwner(j) != 2 && gb.getOwner(j) == gb.getOwner(j+3) && gb.getOwner(j+3) == gb.getOwner(j+6)){
if (gb.getOwner(j) == 0) System.out.println("CPU wins");
else System.out.println("Player wins");
return false;
}
}
//checking for diagonals
if (gb.getOwner(0) != 2 && gb.getOwner(0) == gb.getOwner(4) && gb.getOwner(4) == gb.getOwner(8)){
if (gb.getOwner(0) == 0) System.out.println("CPU wins");
else System.out.println("Player wins");
return false;
}
if (gb.getOwner(2) != 2 && gb.getOwner(2) == gb.getOwner(4) && gb.getOwner(4) == gb.getOwner(6)){
if (gb.getOwner(2) == 0) System.out.println("CPU wins");
else System.out.println("Player wins");
return false;
}
//ends the game, if all spaces are filled, but 3 in a line has not been reached
if (totalTurns < 9) return true;
System.out.println("There is no winner!");
return false;
}
}
public class Tile {
boolean isOwnedByPlayer;
boolean isOwnedByCPU;
public Tile(){
isOwnedByPlayer = false;
isOwnedByCPU = false;
}
public void setOwnedByPlayer(){
isOwnedByPlayer = true;
}
public void setOwnedByCPU(){
isOwnedByCPU = true;
}
public String toString(){
if (isOwnedByPlayer) return "X";
else if (isOwnedByCPU) return "O";
else return "-";
}
}
Edit: Updated the code, should now be working.
The comments and documentation is kinda blah, but you can fix that yourself should you want to.
Also I have not set up preconditions, which you might want too, if you are handing it in as a exercise.
Feel free to use it as your own, just be careful your teacher dont read these forums :-)
Ohh yeah, the ai is still just randoming its moves. Thats a big one, ill leave that one to you