public Position determineMove(TicTacToeBoard state, TicTacToeBoard otherState) { for (int i = 0; i < state.boardConfig.GetLength(0); i++) { for (int j = 0; j < state.boardConfig.GetLength(1); j++) { if (state.boardConfig[i, j] != otherState.boardConfig[i, j]) { Position newPos = new Position(i, j); return(newPos); } } } return(null); }
public TicTacToeBoard copy( ) { TicTacToeBoard copyBoard = new TicTacToeBoard( ); copyBoard.alpha = this.alpha; copyBoard.beta = this.beta; for (int i = 0; i < boardConfig.GetLength(0); i++) { for (int j = 0; j < boardConfig.GetLength(1); j++) { copyBoard.boardConfig[i, j] = this.boardConfig[i, j]; } } return(copyBoard); }
//reset instead of closing and opening game private void Reset() { //reset all instances of globals oTurn = true; playerTurn = true; playerSelected = false; newBoard = new TicTacToeBoard( ); aiChoices = new List <TicTacToeBoard>(); won = null; aDraw = false; xWins = false; oWins = false; }
//test if we are in a terminal state private bool TerminalTest(TicTacToeBoard state) { //Terminal State if we win Position[] winStates = WinState(state); if (winStates != null) { return(true); } //if not win, if the parts of the board is empty, game doesn't end for (int i = 0; i < state.boardConfig.GetLength(0); i++) { for (int j = 0; j < state.boardConfig.GetLength(1); j++) { if (state.boardConfig[i, j] == 0) { return(false); } } } //board is full, terminal state and we didn't win return(true); }
//get the children from current state private Queue <TicTacToeBoard> GenerateSuccessors(TicTacToeBoard state, ref bool tempOTurn, ref int counter) { Queue <TicTacToeBoard> children = new Queue <TicTacToeBoard>(); for (int i = 0; i < state.boardConfig.GetLength(0); i++) { for (int j = 0; j < state.boardConfig.GetLength(1); j++) { TicTacToeBoard copy = state.copy(); if (copy.boardConfig[i, j] == 0) { if (counter == 0) { aiChoices.Add(copy); } copy.boardConfig[i, j] = (tempOTurn ? 1 : 2); children.Enqueue(copy); } } } counter++; return(children); }
private int Min_value(ref TicTacToeBoard state, ref bool tempOTurn, ref int counter, int depth) { if ((depth == 4) || TerminalTest(state)) { return(utility(ref state, depth, ref tempOTurn)); } int v = 1000; Queue <TicTacToeBoard> children = GenerateSuccessors(state, ref tempOTurn, ref counter); while (children.Count != 0) { TicTacToeBoard next = children.Dequeue(); tempOTurn = !tempOTurn; v = Math.Min(v, Max_value(ref next, ref tempOTurn, ref counter, depth)); state.cost = v; if (v <= state.alpha) { return(v); } state.beta = Math.Min(v, state.beta); } return(v); }
//utility function of Alpha beta pruning - will only enter is terminal state private int utility(ref TicTacToeBoard state, int depth, ref bool tempOTurn) //replace this with file input of all possible states - and weights { int cost = 0; for (int i = 0; i < state.boardConfig.GetLength(0); i++) { for (int j = 0; j < state.boardConfig.GetLength(1); j++) { if (oTurn) { if (state.boardConfig[i, j] == 1) { if (i + 1 < state.boardConfig.GetLength(0)) { if (i + 2 < state.boardConfig.GetLength(0)) { if (state.boardConfig[i + 2, j] == state.boardConfig[i + 1, j] && state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { if (i - 1 >= 0 && state.boardConfig[i - 1, j] != state.boardConfig[i, j]) { cost += 10; } } } if (j + 1 < state.boardConfig.GetLength(1)) { if (j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i, j + 2] == state.boardConfig[i, j + 1] && state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { if (j - 1 >= 0 && state.boardConfig[i, j - 1] != state.boardConfig[i, j]) { cost += 10; } } } if (i + 1 < state.boardConfig.GetLength(0) && j + 1 < state.boardConfig.GetLength(1)) { if (i + 2 < state.boardConfig.GetLength(0) && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i + 2, j + 2] == state.boardConfig[i + 1, j + 1] && state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { if (i - 1 >= 0 && j - 1 >= 0 && state.boardConfig[i - 1, j - 1] != state.boardConfig[i, j]) { cost += 10; } } } if (i - 1 >= 0 && j + 1 < state.boardConfig.GetLength(1)) { if (i - 2 >= 0 && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i - 2, j + 2] == state.boardConfig[i - 1, j + 1] && state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { if (i + 1 < state.boardConfig.GetLength(0) && j - 1 >= 0 && state.boardConfig[i + 1, j - 1] != state.boardConfig[i, j]) { cost += 10; } } } } else if (state.boardConfig[i, j] == 2) { if (i + 1 < state.boardConfig.GetLength(0)) { if (i + 2 < state.boardConfig.GetLength(0)) { if (state.boardConfig[i + 2, j] == state.boardConfig[i + 1, j] && state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { if (i - 1 >= 0 && state.boardConfig[i - 1, j] != state.boardConfig[i, j]) { cost -= 10; } } } if (j + 1 < state.boardConfig.GetLength(1)) { if (j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i, j + 2] == state.boardConfig[i, j + 1] && state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { if (j - 1 >= 0 && state.boardConfig[i, j - 1] != state.boardConfig[i, j]) { cost -= 10; } } } if (i + 1 < state.boardConfig.GetLength(0) && j + 1 < state.boardConfig.GetLength(1)) { if (i + 2 < state.boardConfig.GetLength(0) && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i + 2, j + 2] == state.boardConfig[i + 1, j + 1] && state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { if (i - 1 >= 0 && j - 1 >= 0 && state.boardConfig[i - 1, j - 1] != state.boardConfig[i, j]) { cost -= 10; } } } if (i - 1 >= 0 && j + 1 < state.boardConfig.GetLength(1)) { if (i - 2 >= 0 && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i - 2, j + 2] == state.boardConfig[i - 1, j + 1] && state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { if (i + 1 < state.boardConfig.GetLength(0) && j - 1 >= 0 && state.boardConfig[i + 1, j - 1] != state.boardConfig[i, j]) { cost -= 10; } } } } } else if (!oTurn) { if (state.boardConfig[i, j] == 2) { if (i + 1 < state.boardConfig.GetLength(0)) { if (i + 2 < state.boardConfig.GetLength(0)) { if (state.boardConfig[i + 2, j] == state.boardConfig[i + 1, j] && state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { if (i - 1 >= 0 && state.boardConfig[i - 1, j] != state.boardConfig[i, j]) { cost += 10; } } } if (j + 1 < state.boardConfig.GetLength(1)) { if (j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i, j + 2] == state.boardConfig[i, j + 1] && state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { if (j - 1 >= 0 && state.boardConfig[i, j - 1] != state.boardConfig[i, j]) { cost += 10; } } } if (i + 1 < state.boardConfig.GetLength(0) && j + 1 < state.boardConfig.GetLength(1)) { if (i + 2 < state.boardConfig.GetLength(0) && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i + 2, j + 2] == state.boardConfig[i + 1, j + 1] && state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { if (i - 1 >= 0 && j - 1 >= 0 && state.boardConfig[i - 1, j - 1] != state.boardConfig[i, j]) { cost += 10; } } } if (i - 1 >= 0 && j + 1 < state.boardConfig.GetLength(1)) { if (i - 2 >= 0 && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i - 2, j + 2] == state.boardConfig[i - 1, j + 1] && state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { cost += 100; } } else if (state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { if (i + 1 < state.boardConfig.GetLength(0) && j - 1 >= 0 && state.boardConfig[i + 1, j - 1] != state.boardConfig[i, j]) { cost += 10; } } } } else if (state.boardConfig[i, j] == 1) { if (i + 1 < state.boardConfig.GetLength(0)) { if (i + 2 < state.boardConfig.GetLength(0)) { if (state.boardConfig[i + 2, j] == state.boardConfig[i + 1, j] && state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { if (i - 1 >= 0 && state.boardConfig[i - 1, j] != state.boardConfig[i, j]) { cost -= 10; } } } if (j + 1 < state.boardConfig.GetLength(1)) { if (j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i, j + 2] == state.boardConfig[i, j + 1] && state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { if (j - 1 >= 0 && state.boardConfig[i, j - 1] != state.boardConfig[i, j]) { cost -= 10; } } } if (i + 1 < state.boardConfig.GetLength(0) && j + 1 < state.boardConfig.GetLength(1)) { if (i + 2 < state.boardConfig.GetLength(0) && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i + 2, j + 2] == state.boardConfig[i + 1, j + 1] && state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { if (i - 1 >= 0 && j - 1 >= 0 && state.boardConfig[i - 1, j - 1] != state.boardConfig[i, j]) { cost -= 10; } } } if (i - 1 >= 0 && j + 1 < state.boardConfig.GetLength(1)) { if (i - 2 >= 0 && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i - 2, j + 2] == state.boardConfig[i - 1, j + 1] && state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { cost -= 100; } } else if (state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { if (i + 1 < state.boardConfig.GetLength(0) && j - 1 >= 0 && state.boardConfig[i + 1, j - 1] != state.boardConfig[i, j]) { cost -= 10; } } } } } } } state.cost = cost; return(cost); }
//test if we have won private Position[] WinState(TicTacToeBoard state) { //loop through everything in the game board - check for win states for (int i = 0; i < state.boardConfig.GetLength(0); i++) { for (int j = 0; j < state.boardConfig.GetLength(1); j++) { //check if current position in empty if (state.boardConfig[i, j] != 0) { if (i - 2 >= 0 && j - 2 >= 0) { if (state.boardConfig[i - 2, j - 2] == state.boardConfig[i - 1, j - 1] && state.boardConfig[i - 1, j - 1] == state.boardConfig[i, j]) { return(new Position[] { new Position(i - 2, j - 2), new Position(i - 1, j - 1), new Position(i, j) }); } } if (j - 2 >= 0) { if (state.boardConfig[i, j - 2] == state.boardConfig[i, j - 1] && state.boardConfig[i, j - 1] == state.boardConfig[i, j]) { return(new Position[] { new Position(i - 2, j), new Position(i - 1, j), new Position(i, j) }); } } if (i + 2 < state.boardConfig.GetLength(0) && j - 2 >= 0) { if (state.boardConfig[i + 2, j - 2] == state.boardConfig[i + 1, j - 1] && state.boardConfig[i + 1, j - 1] == state.boardConfig[i, j]) { return(new Position[] { new Position(i + 2, j - 2), new Position(i + 1, j - 1), new Position(i, j) }); } } if (i - 2 >= 0) { if (state.boardConfig[i - 2, j] == state.boardConfig[i - 1, j] && state.boardConfig[i - 1, j] == state.boardConfig[i, j]) { return(new Position[] { new Position(i - 2, j), new Position(i - 1, j), new Position(i, j) }); } } if (i + 2 < state.boardConfig.GetLength(0)) { if (state.boardConfig[i + 2, j] == state.boardConfig[i + 1, j] && state.boardConfig[i + 1, j] == state.boardConfig[i, j]) { return(new Position[] { new Position(i + 2, j), new Position(i + 1, j), new Position(i, j) }); } } if (i - 2 >= 0 && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i - 2, j + 2] == state.boardConfig[i - 1, j + 1] && state.boardConfig[i - 1, j + 1] == state.boardConfig[i, j]) { return(new Position[] { new Position(i - 2, j + 2), new Position(i - 1, j + 1), new Position(i, j) }); } } if (j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i, j + 2] == state.boardConfig[i, j + 1] && state.boardConfig[i, j + 1] == state.boardConfig[i, j]) { return(new Position[] { new Position(i, j + 2), new Position(i, j + 1), new Position(i, j) }); } } if (i + 2 < state.boardConfig.GetLength(0) && j + 2 < state.boardConfig.GetLength(1)) { if (state.boardConfig[i + 2, j + 2] == state.boardConfig[i + 1, j + 1] && state.boardConfig[i + 1, j + 1] == state.boardConfig[i, j]) { return(new Position[] { new Position(i + 2, j + 2), new Position(i + 1, j + 1), new Position(i, j) }); } } } } } //did not reach a win state return(null); }