public GameBoardState(GameBoardState boardToCopy) { mCount = boardToCopy.mCount; nCount = boardToCopy.nCount; kCount = boardToCopy.kCount; boardState = new bool?[mCount, nCount]; MaxStoneCount = boardToCopy.MaxStoneCount; CurrentStoneCount = boardToCopy.CurrentStoneCount; for (int i = 0; i < mCount; i++) { for (int j = 0; j < nCount; j++) { boardState[i, j] = boardToCopy.boardState[i, j]; } } }
public GameBoard() { InitializeComponent(); int mCount = 4; int nCount = 5; int kCount = 4; int start_x = 10; int start_y = 20; int CellWidth = 40; int CellHeight = 40; // initialize game board for (int i = 0; i < mCount; i++) { for (int j = 0; j < nCount; j++) { Button cellButton = new Button(); cellButton.Top = start_x + i * CellHeight; cellButton.Left = start_y + j * CellWidth; cellButton.Width = CellWidth; cellButton.Height = CellHeight; cellButton.Text = ""; cellButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); cellButton.Name = string.Format("button_{0}_{1}", i, j); cellButton.Click += new EventHandler(cellClick); cellButton.BackColor = Color.Gray; this.boardPanel.Controls.Add(cellButton); } } // human starts first isMachine = false; machineFirstMove = true; this.gameBoardState = new GameBoardState(mCount, nCount, kCount); }
void cellClick(object sender, EventArgs e) { Button clickedButton = sender as Button; String[] tokens = clickedButton.Name.Split('_'); ClickOnButton(clickedButton); List<String> configList = new List<String>(); // human plays a move GameState gameState = this.gameBoardState.PerformClick( int.Parse(tokens[1]), int.Parse(tokens[2]), isMachine, out configList); UpdateBoardBasedOnState(gameState, configList); // machine is on if (isMachine) { int row = -1; int column = -1; // in all game levels, this is common // if we have a chance to win by clicking anywhere, click // else if we know of a cell where opponent can win by clicking // we will try to stop bool machineCanWin = this.gameBoardState.GetWinningCell( isMachine, out row, out column); if (machineCanWin) { gameUpdate(row, column, isMachine); return; } bool humanCanWin = this.gameBoardState.GetWinningCell( !isMachine, out row, out column); if (humanCanWin) { gameUpdate(row, column, isMachine); return; } // row and column are unchanged in this stage // Hard strategy GameBoardState machineTempBoardState = new GameBoardState(this.gameBoardState); // try to figure out if machine wins in next one move machineTempBoardState.GetBestCell(isMachine, out row, out column); int tempRow = row; int tempColumn = column; machineTempBoardState.PerformClick(row, column, isMachine, out configList); bool machineCanWinSecond = machineTempBoardState.GetWinningCell(isMachine, out row, out column); // row and column changed twice // first change started at GetBestCell // second change started at GetWinningCell // the change at GetBestCell should be saved // if machne can win in one step if (machineCanWinSecond || machineFirstMove) { row = tempRow; column = tempColumn; machineFirstMove = false; } // row and column is unchanged // if the winning cell is unfound else { // try to figure out if human wins in next two moves GameBoardState humanTempBoardState = new GameBoardState(this.gameBoardState); humanTempBoardState.GetBestCell(!isMachine, out row, out column); tempRow = row; tempColumn = column; humanTempBoardState.PerformClick(row, column, !isMachine, out configList); bool humanCanWinSecond = humanTempBoardState.GetWinningCell( !isMachine, out row, out column); if (humanCanWinSecond) { row = tempRow; column = tempColumn; } else { Console.WriteLine("Alpha Beta"); // Apply the Alpha Beta Pruning GameBoardState alphaBetaBoardState = new GameBoardState( this.gameBoardState); // if this depth increases, the time will increases // but there is a hard limit of 10 seconds int[] bestMove = alphaBetaBoardState.Minimax( 20, isMachine, int.MinValue, int.MaxValue, row, column, DateTime.Now); row = bestMove[1]; column = bestMove[2]; } } gameUpdate(row, column, isMachine); return; } }