public static Board.State[,] Play(Board.State[,] Last) { Board.State[,] ReturnState; List <Node> FoundNode = Node.Neighbourhood[GetLevel(Last)]; List <Node> Plays = new List <Node>(); int rot = 0; int mir = 0; foreach (Node Play in FoundNode) { if (Play.BoardsEqual(Last, out rot, out mir)) { Plays = new List <Node>(Play.Children); break; } } Node Selected = new Node(); FoundNode = new List <Node>(Plays); DiscardLosing(); GetWin(); if (Selected.Win != Board.State.P2) { Selected = FindTrap(); } if (!Plays.Contains(Selected)) { if (Plays.Count != 0) { Selected = Plays.OrderBy(o => o.Value).Last(); Console.WriteLine("Picking Last, " + Selected.Value); } else { Selected = FoundNode.Last(); } } //Restore to our original orientation and mirror Selected.Rotate(rot); Selected.Unmirror(mir); ReturnState = Selected.Board; return(ReturnState); //-------------------------------- //AI actions //Finds if one of the possible plays leads to a perfect win. Play is the AI play, SubPlay is the Player Play. If a play has all player plays lead to AI win, we can return that. Node FindTrap() { //we should expand this to find more traps hidden in our tree foreach (Node Play in Plays) { foreach (Node SubPlay in Play.Children) { bool Trap = true; foreach (Node OurPlay in SubPlay.Children) { if (SubPlay.Win != Board.State.P2) { Trap = false; break; } } if (Trap) { return(Play); } } } return(new Node()); } void DiscardLosing() { List <Node> Remove = new List <Node>(); foreach (Node a in Plays) { foreach (Node q in a.Children) { if (q.Win == Board.State.P1) { Remove.Add(a); } } } Plays = Plays.Except(Remove).ToList(); } void GetWin() { Node q = Plays.Find(o => o.Win == Board.State.P2); if (q != null) { Selected = q; } } }