//扩展结点 private void expand(nodes node) { simap board2 = new CDC.simap(); board2 = node.board.createDeepClone(); List <Move> atkandmoveList; //移动指令序列 List <Move> flipList; //攻击指令序列 atkandmoveList = AI_tools.getallmove(node.board); //移动指令变为对方可移动指令 flipList = AI_tools.getallfliplist(node.board); //攻击指令变为对方可攻击指令 for (int i = 0; i < atkandmoveList.Count; i++) //对攻击指令进行遍历 { node.child.Add(new nodes()); //添加子节点 node.child[i].movtion = atkandmoveList[i]; //添加攻击移动指令进指令集 node.child[i].board = board2.createDeepClone(); //复制地图信息进入子节点 node.child[i].board.executemove(node.child[i].board, atkandmoveList[i]); } for (int i = 0; i < flipList.Count; i++) //对翻棋指令进行遍历 { node.child.Add(new nodes()); //添加子节点 node.child[i + atkandmoveList.Count].movtion = flipList[i]; //添加翻棋指令进指令集 node.child[i + atkandmoveList.Count].board = board2.createDeepClone(); //复制地图信息进入子节点 node.child[i + atkandmoveList.Count].board.executemove(node.child[i + atkandmoveList.Count].board, flipList[i]); //在子节点地图上执行指令 } }
private void atk_expand(nodes node) { simap board2 = new CDC.simap(); board2 = node.board.createDeepClone(); List <Move> atkandmoveList = new List <Move>();//移动指令序列 List <Move> flippingList = new List <Move>(); node.visit = 1; //节点已经被访问过 atkandmoveList = AI_tools.getallmove(node.board); //移动指令变为对方可移动指令 flippingList = AI_tools.getallfliplist(node.board); for (int i = 0; i < atkandmoveList.Count; i++) //对攻击指令进行遍历 { node.child.Add(new nodes()); //添加子节点 node.child[i].movtion = atkandmoveList[i].deepclone(); //添加攻击移动指令进指令集 node.child[i].board = board2.createDeepClone(); //复制地图信息进入子节点 node.child[i].board.executemove(node.child[i].board, atkandmoveList[i]); node.child[i].depth = (node.depth) + 1; node.child[i].parent = node; } for (int i = 0; i < flippingList.Count; i++) { node.child.Add(new nodes()); //添加子节点 node.child[i + atkandmoveList.Count].movtion = flippingList[i].deepclone(); //添加翻棋移动指令进指令集 node.child[i + atkandmoveList.Count].board = board2.createDeepClone(); //复制地图信息进入子节点 node.child[i + atkandmoveList.Count].depth = (node.depth) + 1; node.child[i + atkandmoveList.Count].parent = node; node.child[i + atkandmoveList.Count].visit = -3;//翻棋节点不会有子节点,表示为翻棋节点 } }
//Main logic module public Move Misirlou_v3(Map vmap) { timer.Start(); simap map = new CDC.simap(); map = map.createDeepClone(vmap); int now_sim = 0; //现在的模拟数 nodes rootnode = new nodes(); //创造根节点 rootnode.board = map; //复制地图进入根节点 List <Move> moveList = AI_tools.getallmove(rootnode.board); //根节点时的可行动列表 List <Move> flipList = AI_tools.getallfliplist(rootnode.board); //根节点时的翻棋列表 for (int a = 1; a <= max_sim; a++) { if (timer.ElapsedMilliseconds <= Lim_time) { UCT(rootnode, map.currentside, map.firstplayer); now_sim++; } else { break; } } Move bestmove = best_move(rootnode); timer.Stop(); timer.Reset(); return(bestmove); }
private void doRandomMove(simap board) { List <Move> alllist = AI_tools.getmovflip(board); int tmp = rand.Next(alllist.Count); board.executemove(board, alllist[tmp]); }
public Move Misirlou_v3(block[][] matrix, int currentside, int firstplayer, int turn)//Monte-Carlo { timer.Start(); int now_sim = 0; //现在的模拟数 nodes rootnode = new nodes(); //创造根节点 rootnode.board = matrix; //复制地图进入根节点 rootnode.side = currentside; //根节点的玩家参数 List <Move> moveList = AI_tools.getallmove(rootnode.board, currentside); //根节点时的可行动列表 List <Move> flipList = AI_tools.getallfliplist(rootnode.board); //根节点时的翻棋列表 for (int a = 1; a <= max_sim; a++) { UCT(rootnode, currentside, firstplayer); now_sim++; } Move bestmove = best_move(rootnode); timer.Stop(); Lef_time -= timer.ElapsedMilliseconds; timer.Reset(); return(bestmove); }
//扩展结点 private void expand(nodes node) { block[][] board2 = node.board; List <Move> atkandmoveList; //移动指令序列 List <Move> flippingList; //攻击指令序列 int nexTeamCol; //列举可能行动之前检查行动队伍是否发生改变 board2.incTurnCount(); //回合数+1 nexTeamCol = (node.side + 1) % 2; //蓝队变红队,红队变蓝队,可行动方交换 flippingList = AI_tools.get((node.side + 1) % 2, board2); //移动指令变为对方可移动指令 atkandmoveList = AI_tools.getAllAttackMoves((node.side + 1) % 2, board2); //攻击指令变为对方可攻击指令 for (int i = 0; i < atkandmoveList.Count; i++) //对攻击指令进行遍历 { node.child.Add(new nodes()); //添加子节点 node.child[i].movtion = atkandmoveList[i]; //添加攻击指令进指令集 node.child[i].board = board2; node.child[i].board.atkandmove(atkandmoveList[i]); node.child[i].side = nexTeamCol; //进入下一手、 } for (int i = 0; i < flippingList.Count; i++) //对翻棋指令进行遍历 { node.child.Add(new nodes()); //添加子节点 node.child[i + atkandmoveList.Count].movtion = flippingList[i]; //添加移动指令进指令集 node.child[i + atkandmoveList.Count].board = board2; //复制地图信息 node.child[i + atkandmoveList.Count].board.atkandmove(flippingList[i]); node.child[i + atkandmoveList.Count].side = nexTeamCol; //进入下一手 } }
private void click(object sender, EventArgs e) //翻棋子事件 { string name = (sender as PictureBox).Name; //名字 string number = name.Substring(10); //字符串第十位开始截取,即截取编号 int index = Convert.ToInt32(number); //编号转换字符串为整形 int i, j; int currentcolor = 2; i = (index - 1) / 8; //被选择的行 j = (index - 1) % 8; //被选择的列 if (vmap.Matrix[i, j].flip == 0) //点击对象为未翻开的对象时翻棋 { if (vmap.turncount == 1) //一局开始 { vmap.firstplayer = vmap.Matrix[i, j].item.side; //第一个棋子即为第一玩家的颜色 vmap.secondplayer = (vmap.Matrix[i, j].item.side + 1) % 2; display(vmap.firstplayer); } clicknode.movtion.froX = i; clicknode.movtion.froY = j; atkandmove(vmap, clicknode); } else if (vmap.Matrix[i, j].flip == 1) //点击的对象为已翻开的棋子 { if (vmap.currentside == 0) //为先手方的时候 { currentcolor = vmap.firstplayer; } else if (vmap.currentside == 1)//为后手方的时候 { currentcolor = vmap.secondplayer; } if (vmap.Matrix[i, j].item.side == currentcolor)//为本方棋子的时候 { clicknode.movtion.froX = i; clicknode.movtion.froY = j; return; } if (vmap.Matrix[i, j].item.side == (currentcolor + 1) % 2 || vmap.Matrix[i, j].item.side == 2)//为对方棋子的时候或者空的时候 { clicknode.movtion.desX = i; clicknode.movtion.desY = j; } atkandmove(vmap, clicknode); score(vmap); if (checkboard(clicknode, vmap) != 0) { AI_tools.resetground(vmap); MessageBox.Show("Game End!"); } } }
private bool domoveandatk(simap board, int currentside) { List <Move> atkandmovelist = AI_tools.getallmove(board); if (atkandmovelist.Count == 0) { return(false); } int tmp = rand.Next(atkandmovelist.Count); board.executemove(board, atkandmovelist[tmp]); return(true); }
private bool doRandomflip(simap board, int currentside) { List <Move> fliplist = AI_tools.getallfliplist(board); if (fliplist.Count == 0) { return(false); } int tmp = rand.Next(fliplist.Count); board.executemove(board, fliplist[tmp]); return(true); }
private bool doonlyMove(simap board, int currentside) { List <Move> movelist = AI_tools.getonlymove(board); if (movelist.Count == 0) { return(false); } int tmp = rand.Next(movelist.Count); board.executemove(board, movelist[tmp]); return(true); }
private void button2_Click(object sender, EventArgs e) { AI ai = new AI(); nodes movnod = new CDC.nodes(); movnod = ai.alpha_Beta(vmap); atkandmove(vmap, movnod);//调用先手AI score(vmap); if (checkboard(movnod, vmap) != 0) { AI_tools.resetground(vmap); MessageBox.Show("Game End!"); } }
private double checkboard(simap map) { int redCount = 0; int blueCount = 0; List <Move> alllist = AI_tools.getmovflip(map); if ((map.turncount >= 300) || (alllist.Count == 0))//Limit number of Draw { return(0.5); } for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if (map.Matrix[i, j].item.side == 0) //为红方 { redCount++; //红加1 } if (map.Matrix[i, j].item.side == 1) //为蓝方 { blueCount++; //蓝加1 } } } if (redCount == 0) //Blue win! { if ((map.firstplayer == 0 && map.currentside == 0) || (map.firstplayer == 1 && map.currentside == 1)) //map.currentside is red { return(0); } if ((map.firstplayer == 1 && map.currentside == 0) || (map.firstplayer == 1 && map.currentside == 0))//map.currentside is blue { return(1); } } if (blueCount == 0) //Red win ! { if ((map.firstplayer == 1 && map.currentside == 0) || (map.firstplayer == 1 && map.currentside == 0)) //map.currentside is blue { return(0); } if ((map.firstplayer == 0 && map.currentside == 0) || (map.firstplayer == 1 && map.currentside == 1))//map.currentside is red { return(1); } } return(-1);//游戏未结束则返回-1 }
private bool check_suicide(Map vmap, Move bestmove) { bool re_bool = false; simap map = new CDC.simap(); Move move = new Move(); move = bestmove.deepclone(); map = map.createDeepClone(vmap); map.executemove(map, move); if (AI_tools.getcheckone(map, bestmove) == true) { re_bool = true; } return(re_bool); }
public Form1() { InitializeComponent(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { Control[] pic = this.Controls.Find("pictureBox" + (i * 8 + j + 1), false); vmap.Matrix[i, j].container = pic[0] as PictureBox; } } AI_tools.resetground(vmap);//重置棋盘 Judge_system(vmap); }
private Move getnear(simap map, int currentside) { double distance = 0; double mindistance = 100; List <Move> movtionlist = new List <Move>(); Move nearmove = new Move(); movtionlist = AI_tools.getallmove(map); foreach (Move movtion in movtionlist) { distance = (Math.Sqrt((Math.Pow(Math.Abs(movtion.desY - movtion.froY), 2) + Math.Pow(Math.Abs(movtion.desX - movtion.froX), 2)))); if (distance < mindistance) { nearmove = movtion; } } if (mindistance == 100) { nearmove = movtionlist[rand.Next(movtionlist.Count)]; } return(nearmove); }
private nodes smartflipping(nodes rootnode, Map map) { int flippedpiece = 0; double temp_value = 0; double min_risk = 100; int mark = 0; nodes nodesmove = new nodes(); List <Move> flippingList = new List <Move>(); flippingList = AI_tools.getallfliplist(rootnode.board); Map mapasses = new Map(); mapasses = map.createDeepClone(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if (rootnode.board.Matrix[i, j].flip == 1) { flippedpiece += 1; } } } //第一阶段,只要相邻格有敌方棋子则不翻 for (int i = 0; i < flippingList.Count; i++) { for (int a = 0; a < 4; a++) { for (int b = 0; b < 8; b++) { if ((((Math.Abs(a - flippingList[i].froX) == 0) && (Math.Abs(b - flippingList[i].froY) == 1)) || ((Math.Abs(a - flippingList[i].froX) == 1) && (Math.Abs(b - flippingList[i].froY) == 0))) && //与翻棋坐标相邻的 ((rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.firstplayer && rootnode.board.currentside == 1) || (rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.secondplayer && rootnode.board.currentside == 0))) //周围的非己方棋子 { mark++; } } } if (mark != 0) { flippingList.Remove(flippingList[i]); //则去掉这样一个元素 mark = 0; //清除 continue; } } if (flippingList.Count != 0)//存在保守翻棋策略 { nodesmove.remain_flip_number = flippingList.Count; nodesmove.movtion.froX = flippingList[rand.Next(flippingList.Count)].froX; nodesmove.movtion.froY = flippingList[rand.Next(flippingList.Count)].froY; } //第二阶段,不存在完全保守的策略时 else if (flippingList.Count == 0) //不存在保守翻棋策略 { flippingList = AI_tools.getallfliplist(rootnode.board); //重新刷进flippinglist mark = 0; //清除mark for (int i = 0; i < flippingList.Count; i++) { for (int a = 0; a < 4; a++) { for (int b = 0; b < 8; b++) { if ((((Math.Abs(a - flippingList[i].froX) == 0) && (Math.Abs(b - flippingList[i].froY) == 1)) || ((Math.Abs(a - flippingList[i].froX) == 1) && (Math.Abs(b - flippingList[i].froY) == 0))) && //与翻棋坐标相邻的 ((rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.firstplayer && rootnode.board.currentside == 1) || (rootnode.board.Matrix[a, b].flip == 1 && rootnode.board.Matrix[a, b].item.side == rootnode.board.secondplayer && rootnode.board.currentside == 0))) //周围的已经翻开的非己方棋子 { temp_value = cal_risk(a, b, map); if (temp_value == -1000)//绝对会被吃掉的情况 { mark++; } else { flippingList[i].risk += cal_risk(a, b, map); } } } } if (mark != 0) { flippingList.Remove(flippingList[i]); //则去掉这样一个元素 mark = 0; //清除 continue; } } for (int i = 0; i < flippingList.Count; i++) //选择威胁值最小的翻棋步骤 { if (flippingList[i].risk <= min_risk) //越高的正值 { nodesmove.remain_flip_number = flippingList.Count; nodesmove.movtion.froX = flippingList[i].froX; nodesmove.movtion.froY = flippingList[i].froY; } } } return(nodesmove); }
private void button5_Click(object sender, EventArgs e) { AI_tools.resetground(vmap); }
public nodes subAI_Evaluate(Map map) { simap map2 = new CDC.simap(); map2 = map2.createDeepClone(map); //复制一下地图 List <Move> movtionlist = new List <Move>(); //移动指令表 List <Move> fliplist = new List <Move>(); //翻棋指令表 List <Move> Alllist = new List <Move>(); //翻棋指令表 Move bestmove = new CDC.Move(); //最佳动作 Move bestflip = new Move(); //最佳翻棋 Move startflip = new Move(); //起始翻棋 nodes bestnode = new nodes(); if (map2.turncount == 1) //一局开始 { fliplist = AI_tools.getallfliplist(map2); //可翻行动列表 startflip = fliplist[rand.Next(fliplist.Count)]; //起始翻 map2.firstplayer = map.Matrix[startflip.froX, startflip.froY].item.side; //第一个棋子即为第一玩家的颜色 map2.secondplayer = (map.Matrix[startflip.froX, startflip.froY].item.side + 1) % 2; //第二玩家为另一颜色 map2.currentside = map2.firstplayer; bestnode.movtion.froX = startflip.froX; bestnode.movtion.froY = startflip.froY; bestnode.movtion.desX = startflip.desX; bestnode.movtion.desY = startflip.desY; return(bestnode); } else//非开局 { int point; int Maxpoint = 0; movtionlist = AI_tools.getallmove(map2); //获取所有可行指令 foreach (Move movtion in movtionlist) //遍历进攻选项 { point = AI_tools.point_Evaluate(map2, movtion); //计算进攻选项得点 if (point > Maxpoint) //判断得点最大 { Maxpoint = point; bestmove = movtion; bestnode.movtion.froX = bestmove.froX; bestnode.movtion.froY = bestmove.froY; bestnode.movtion.desX = bestmove.desX; bestnode.movtion.desY = bestmove.desY; return(bestnode); } } if (Maxpoint == 0)//为移动指令时 { if (movtionlist.Count != 0) { bestmove = getnear(map2, map2.currentside); } Alllist = AI_tools.getmovflip(map2); if (Alllist.Count == 0) { checkboard(map2); } bestmove = Alllist[rand.Next(Alllist.Count)];//无有效步的时候生成随机步数 } } bestnode.movtion.froX = bestmove.froX; bestnode.movtion.froY = bestmove.froY; bestnode.movtion.desX = bestmove.desX; bestnode.movtion.desY = bestmove.desY; return(bestnode); }
private double score(nodes node) { List <Move> flippingList = new List <Move>(); flippingList = AI_tools.getallfliplist(node.board); double point = 0; double score = 0; for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if ((node.board.Matrix[i, j].item.side == node.board.firstplayer && currentside == 0 && node.board.Matrix[i, j].flip == 1) || (node.board.Matrix[i, j].item.side == node.board.secondplayer && currentside == 1 && node.board.Matrix[i, j].flip == 1)) //针对根结点行动方的估值 //确保在相同手时使用最大值,对方手时使用最小值 { switch (node.board.Matrix[i, j].item.type) { case chesstype.jiang: point = 20; break; case chesstype.shi: point = 10; break; case chesstype.xiang: point = 6; break; case chesstype.che: point = 4; break; case chesstype.ma: point = 3; break; case chesstype.zu: point = 2; break; case chesstype.pao: point = 6; break; case chesstype.blank: //移动 point = 0; break; } } if ((node.board.Matrix[i, j].item.side == node.board.firstplayer && currentside == 1 && node.board.Matrix[i, j].flip == 1) || (node.board.Matrix[i, j].item.side == node.board.secondplayer && currentside == 0 && node.board.Matrix[i, j].flip == 1)) { switch (node.board.Matrix[i, j].item.type) { case chesstype.jiang: point = -20; break; case chesstype.shi: point = -10; break; case chesstype.xiang: point = -6; break; case chesstype.che: point = -4; break; case chesstype.ma: point = -3; break; case chesstype.zu: point = -2; break; case chesstype.pao: point = -6; break; case chesstype.blank: //移动 point = 0; break; } } if (node.board.Matrix[i, j].item.side == 2) { point = 0; } for (int b = 0; b < 4; b++) { for (int a = 0; a < 8; a++) { if (((Math.Abs(b - i) <= 1) && (Math.Abs(a - j) <= 1)) && node.board.Matrix[b, a].flip == 1 && node.board.Matrix[b, a].item.side != 2) { Move movtion = new Move(); Move movtion2 = new Move(); movtion.froX = i; movtion.froY = j; movtion.desX = b; movtion.desY = a; if (GameController.checkmove(node.board, movtion) == true) { point = point * 1.25; } movtion2.froX = b; movtion2.froY = a; movtion2.desX = i; movtion2.desY = j; if (GameController.checkmove(node.board, movtion2) == true) { point = point * 0.75; } } } } score += point; } } if (node.movtion.desX == -1 && node.movtion.desY == -1 && node.movtion.froX != -1 && node.movtion.froY != -1)//节点为翻棋面节点时 { point = cal_flipping(node); for (int b = 0; b < 4; b++) { for (int a = 0; a < 8; a++) { if (((Math.Abs(b - node.movtion.froX) <= 1) && (Math.Abs(a - node.movtion.froY) <= 1)) && node.board.Matrix[b, a].flip == 1 && node.board.Matrix[b, a].item.side != 2) { Move movtion = new Move(); Move movtion2 = new Move(); movtion.froX = node.movtion.froX; movtion.froY = node.movtion.froY; movtion.desX = b; movtion.desY = a; if (GameController.checkmove(node.board, movtion) == true) { point = point * 1.25; } movtion2.froX = b; movtion2.froY = a; movtion2.desX = node.movtion.froX; movtion2.desY = node.movtion.froY; if (GameController.checkmove(node.board, movtion2) == true) { point = point * 0.75; } } } } score += point; } return(score); }
private void cal_Proba(Map map) { int unflip_blue_che = map.blueche; int unflip_blue_ma = map.bluema; int unflip_blue_jiang = map.bluejiang; int unflip_blue_shi = map.blueshi; int unflip_blue_xiang = map.bluexiang; int unflip_blue_zu = map.bluezu; int unflip_blue_pao = map.bluepao; int unflip_red_che = map.redche; int unflip_red_ma = map.redma; int unflip_red_jiang = map.redjiang; int unflip_red_shi = map.redshi; int unflip_red_xiang = map.redxiang; int unflip_red_zu = map.redzu; int unflip_red_pao = map.redpao; simap sim_map = new simap(); sim_map = sim_map.createDeepClone(map); List <Move> flipping = new List <Move>(); flipping = AI_tools.getallfliplist(sim_map); int all_unflip = flipping.Count; for (int i = 0; i < 4; i++) { for (int j = 0; j < 8; j++) { if ((map.Matrix[i, j].item.side == 1) && (map.Matrix[i, j].flip == 1))//蓝方 { switch (map.Matrix[i, j].item.type) { case chesstype.che: unflip_blue_che -= 1; break; case chesstype.ma: unflip_blue_ma -= 1; break; case chesstype.jiang: unflip_blue_jiang -= 1; break; case chesstype.pao: unflip_blue_pao -= 1; break; case chesstype.zu: unflip_blue_zu -= 1; break; case chesstype.shi: unflip_blue_shi -= 1; break; case chesstype.xiang: unflip_blue_xiang -= 1; break; } } if (map.Matrix[i, j].item.side == 0)//红方 { switch (map.Matrix[i, j].item.type) { case chesstype.che: unflip_red_che -= 1; break; case chesstype.ma: unflip_red_ma -= 1; break; case chesstype.jiang: unflip_red_jiang -= 1; break; case chesstype.pao: unflip_red_pao -= 1; break; case chesstype.zu: unflip_red_zu -= 1; break; case chesstype.shi: unflip_red_shi -= 1; break; case chesstype.xiang: unflip_red_xiang -= 1; break; } } } } map.Pbche = unflip_blue_che / all_unflip; map.Pbjiang = unflip_blue_jiang / all_unflip; map.Pbma = unflip_blue_ma / all_unflip; map.Pbxiang = unflip_blue_xiang / all_unflip; map.Pbshi = unflip_blue_shi / all_unflip; map.Pbzu = unflip_blue_zu / all_unflip; map.Pbpao = unflip_blue_pao / all_unflip; map.Prche = unflip_red_che / all_unflip; map.Prjiang = unflip_red_jiang / all_unflip; map.Prma = unflip_red_ma / all_unflip; map.Prxiang = unflip_red_xiang / all_unflip; map.Prshi = unflip_red_shi / all_unflip; map.Przu = unflip_red_zu / all_unflip; map.Prpao = unflip_red_pao / all_unflip; }
private void atkandmove(Map map, nodes node) { #region Branching Factor Part List <Move> flipList = new List <Move>(); List <Move> movelist = new List <Move>(); simap map2 = new CDC.simap(); map2 = map2.createDeepClone(vmap); int branchingF = 0; int flipList_num = 0; int e_flip = AI_tools.getallfliplist(map2).Count; if ((map.currentside == 0 && map.firstplayer == 0) || (map.currentside == 1 && map.firstplayer == 1))//Red { e_flip = (e_flip - map.unflipp_blue); } else if ((map.currentside == 0 && map.firstplayer == 1) || (map.currentside == 1 && map.firstplayer == 0))//Blue { e_flip = (e_flip - map.unflipp_red); } flipList_num = e_flip;//从缩减后改为毫无缩减的状况 movelist = AI_tools.getallmove(map2); flipList = AI_tools.getallfliplist(map2); branchingF = movelist.Count + flipList.Count; allB.Add(branchingF); #endregion Move use = new CDC.Move(); use.froX = node.movtion.froX; use.froY = node.movtion.froY; use.desX = node.movtion.desX; use.desY = node.movtion.desY; //避免将原数据消除 if (use.desX == -1 && use.desY == -1 && use.froX != -1 && use.froY != -1) //AI给出的行动为翻棋 { flipchess(map, use.froX, use.froY); } if (use.froX != -1 && use.froY != -1 && use.desX != -1 && use.desY != -1)//都选定的情况 { if (GameController.checkmove(map, use) == true) { setmove(map, use); } else { use.froX = -1; use.froY = -1; use.desX = -1; use.desY = -1; } } if (map.currentside == 0) { label1.Text = "Current Player: First Player"; } if (map.currentside == 1) { label1.Text = "Current Player: Second Player"; } if ((vmap.currentside + 1) % 2 == 0) //已经实行的那一步的实施方(因为再flpchess和setmove中改变了currentside的值)属于先手或者后手 { vmap.Plyr1move.Add(node); //movtion存入先手List vmap.Plyr_move.Add(node); } else if (((vmap.currentside + 1) % 2 == 1)) { vmap.Plyr2move.Add(node);//movtion存入后手List vmap.Plyr_move.Add(node); } double displayturn = map.turncount - 1; use.froX = -1; use.froY = -1; use.desX = -1; use.desY = -1; }
public nodes alpha_Beta(Map map) { //start rootnode; nodes rootnode = new nodes(); simap board = new simap(); nodes bestnode = new nodes(); List <Move> atkmovtion = new List <Move>(); List <Move> allmovtion = new List <Move>(); double maxscore = -1000; board = board.createDeepClone(map); rootnode.board = board; rootnode.depth = 0;//根节点的深度为零 currentside = rootnode.board.currentside; atkmovtion = AI_tools.getallatk(board); allmovtion = AI_tools.getallmove(board); alphabeta(rootnode); Console.WriteLine("CUT:" + cut + "\r\n\r\n\r\n"); foreach (nodes child in rootnode.child) { if (child.visit == 0) { continue; } else if (maxscore <= child.beta) { maxscore = child.beta; bestnode = child; } } if (deloop(bestnode, map) == true)//6步里2步以上重复 且为bestnode 则跳出 { rootnode.child.Remove(bestnode); if (map.unflipped > 0) { bestnode = smartflipping(rootnode, map); } else if (map.unflipped == 0 && rootnode.child.Count != 0) { foreach (nodes achild in rootnode.child) { if (maxscore <= achild.beta) { maxscore = achild.beta; bestnode = achild; } } } else if (map.unflipped == 0 && rootnode.child.Count == 0) { bestnode = subAI_Evaluate(map); } } if (bestnode.movtion.desX == -1 && bestnode.movtion.desY == -1) { bestnode = smartflipping(rootnode, map); } return(bestnode); }
private void button1_Click(object sender, EventArgs e) //AI battle { int game_limit = 25; //进行试验的游戏局数 int game_noli_limit = game_limit; int games = 1; //初始化为1 double firstAIwin = 0; //先手AI胜利数 double secondAIwin = 0; //后手AI胜利数 double draw = 0; double draw_3 = 0; double draw_4 = 0; double totalturn = 0;//本次模拟总长度 double totalB = 0; AI ai = new AI(); ai2 ai2 = new ai2(); while (games <= game_limit)//没有执行完规定次数时 { List <double> scoreit = new List <double>(); while (vmap.flag == 0)//循环直到游戏结束 { nodes movnod = new CDC.nodes(); if (vmap.currentside == 0)//先手 { movnod = ai.alpha_Beta(vmap); atkandmove(vmap, movnod); //调用先手AI } else if (vmap.currentside == 1) //后手 { movnod = ai2.alpha_Beta(vmap); atkandmove(vmap, movnod);//调用后手AI } textBox1.AppendText("Experiment Game: " + games + "\r\n"); Console.WriteLine("+++++++++++++++++++++++++++++++++++++" + score(vmap)); double temp = score(vmap); scoreit.Add(temp); vmap.flag = checkboard(movnod, vmap); } Console.WriteLine("One Game Finished"); if ((vmap.firstplayer == 0 && vmap.flag == 2) || (vmap.firstplayer == 1 && vmap.flag == 1))//先手AI胜 { Console.WriteLine("First AI win!"); gameresult.Add(scoreit); firstAIwin++; Allturn.Add(vmap.turncount); //记录每局长度 } else if ((vmap.firstplayer == 0 && vmap.flag == 1) || (vmap.firstplayer == 1 && vmap.flag == 2)) //后手AI胜 { Console.WriteLine("Second AI win!"); gameresult.Add(scoreit); secondAIwin++; Allturn.Add(vmap.turncount);//记录每局长度 } else if (vmap.flag == 3) { draw += 1; draw_3 += 1; Allturn.Add(vmap.turncount);//记录每局长度 gameresult.Add(scoreit); } else if (vmap.flag == 4) { draw_4 += 1; AI_tools.resetground(vmap); allB.Clear(); continue; } Console.WriteLine("Number of Games:" + games);//游戏结束后 games++; cal_averageB(allB); allB.Clear(); AI_tools.resetground(vmap); } for (int i = 0; i < game_noli_limit; i++) { totalturn += Allturn[i] - 1; totalB += calB[i]; } textBox1.AppendText("Simulation Ended" + "\r\n"); textBox1.AppendText("FirstAI Winning Ratio:" + (firstAIwin / game_limit) * 100 + "%" + "\r\n"); textBox1.AppendText("SecondAI Winning Ratio:" + (secondAIwin / game_limit) * 100 + "%" + "\r\n"); textBox1.AppendText("Draw Ratio:" + (draw / game_limit) * 100 + "%" + "\r\n"); textBox1.AppendText("Number of Flag 3 draw:" + draw_3 + "\r\n"); textBox1.AppendText("Number of Flag 4 draw:" + draw_4 + "\r\n"); textBox1.AppendText("Avarage Game Length:" + totalturn / game_noli_limit + " turns" + "\r\n"); textBox1.AppendText("Avarage Branching Factor:" + totalB / game_noli_limit + "\r\n"); for (int i = 0; i < win_jiang.Count; i++) { Console.WriteLine(win_jiang[i]); } Console.WriteLine("=====================================================================================================" + "\r\n"); for (int i = 0; i < win_zu.Count; i++) { Console.WriteLine(win_zu[i]); } Console.WriteLine("=====================================================================================================" + "\r\n"); for (int i = 0; i < win_pao.Count; i++) { Console.WriteLine(win_pao[i]); } Console.WriteLine("=====================================================================================================" + "\r\n"); for (int i = 0; i < lose_jiang.Count; i++) { Console.WriteLine(lose_jiang[i]); } Console.WriteLine("=====================================================================================================" + "\r\n"); for (int i = 0; i < lose_zu.Count; i++) { Console.WriteLine(lose_zu[i]); } Console.WriteLine("=====================================================================================================" + "\r\n"); for (int i = 0; i < lose_pao.Count; i++) { Console.WriteLine(lose_pao[i]); } }