public override GameTreeNode NextMove(Board board, GameTreeNode currentNode) { //int winningMove; //priorities: //1. crush humans //2. prevent humans victory //1. just win the game //winningMove = board.GoingToWin(Board.CELL_O); //if (winningMove != 0) { // Console.WriteLine(this.name + ": You have been terminated."); // //do the move // board.PlayerMove(winningMove, this.mark); // //and look for the node to return // foreach (GameTreeNode child in currentNode.children) { // if (child.status.Equals(board)) { // return child; // } // } //} ////2. counter the opponents winning chance //winningMove = board.GoingToWin(Board.CELL_X); //if (winningMove != 0) { // Console.WriteLine(this.name + ": You will pay for your insolence!"); // //do the move // board.PlayerMove(winningMove, this.mark); // //and look for the node to return // foreach (GameTreeNode child in currentNode.children) { // if (child.status.Equals(board)) { // return child; // } // } //} //3. play a move toward the victory foreach (GameTreeNode child in Utils.Shuffle <GameTreeNode>(currentNode.children)) { //foreach (GameTreeNode child in currentNode.children) { if (child.Eval() == true) { Console.WriteLine(this.name + ": I will crush you all!"); board.PlayerMove(child.inputMove, this.mark); return(child); } } //4. there's no winning chance: we take a random available move Console.WriteLine(this.name + ": The board is a lie!"); //board.Move(currentNode.children[0].inputMove, this.mark); //return currentNode.children[0]; //random selection of next node GameTreeNode nextNode = currentNode.RandomChild(); board.PlayerMove(nextNode.inputMove, this.mark); return(nextNode); }
public override GameTreeNode NextMove(Board board, GameTreeNode currentNode) { int movePos = 0; //keep asking for a reasonable move to input: //1 2 3 //4 5 6 //7 8 9 while (!board.PlayerMove(movePos, this.mark)) { Console.WriteLine("What is your next move? [1..9]"); ConsoleKeyInfo kinfo = Console.ReadKey(false); movePos = (int)(kinfo.KeyChar); movePos = movePos - 48; //subtract the char code for '0' Console.WriteLine(); } //look for the child node corresponding to the chosen move and return it foreach (GameTreeNode child in currentNode.children) { if (child.status.Equals(board)) { return(child); } } Console.WriteLine("[Error] Something's wrong with the game tree."); return(null); }
public GameTreeNode[] children; //all the possible configurations for all the possible next moves, //0 children if this node is a winning state, 9 children if it's the node with an empty board public GameTreeNode(GameTreeNode parent, Board status, String mark, int inputMove) { this.parent = parent; this.status = status.ObjectCopy(); this.mark = mark; this.inputMove = inputMove; this.win = false; this.opponentWin = false; this.children = null; }
/// <summary> /// Builds the subtree starting from this node. /// </summary> public void Build() { GameTreeNode newNode; int countEmptyCells = 0; // each empty cell leads to a new children countEmptyCells = this.status.CountEmptyCells(); if (countEmptyCells > 0) { this.children = new GameTreeNode[countEmptyCells]; for (int i = 0; i < 9; i++) { if (this.status.layout[i] == Board.CELL_E) { // create a new node, setting up next possible move newNode = new GameTreeNode(this, this.status, this.NextMark(), i + 1); newNode.status.PlayerMove(i + 1, this.mark); newNode.win = newNode.status.CheckForWin(Board.CELL_O); //|| newNode.status.CheckForTie(); newNode.opponentWin = newNode.status.CheckForWin(Board.CELL_X); // add the new node to the first empty space in the children array for (int j = 0; j < countEmptyCells; j++) { if (this.children[j] == null) { this.children[j] = newNode; break; } } // go deeper only if the game is not over yet if (!newNode.win && !newNode.opponentWin) { newNode.Build(); } } } } }
public virtual GameTreeNode NextMove(Board board, GameTreeNode currentNode) { return(null); }
public GameTree(Board rootBoard, String startingMark) { this.root = new GameTreeNode(null, rootBoard, startingMark, 0); }