/// <summary> /// 根据当前行棋人绘制棋子 /// </summary> /// <param name="curUser">当前行棋人</param> /// <param name="x">棋子横坐标</param> /// <param name="y">棋子纵坐标</param> private void DrawPiece(int curUser, int x, int y) { if (curUser == Globe.USER_1) { g_b.DrawImage(Globe.BLACK, Globe.I2C(x), Globe.I2C(y), 30, 30); // 直接增添新棋子 } else { g_b.DrawImage(Globe.WHITE, Globe.I2C(x), Globe.I2C(y), 30, 30); // 直接增添新棋子 } }
/// <summary> /// 鼠标移动时显示位置标识 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chessBoard_MouseMove(object sender, MouseEventArgs e) { // 游戏开始时有效 if (!game.isOver()) { // 取得横纵索引 int x = Globe.C2I(e.X); int y = Globe.C2I(e.Y); // 绘制标记 g_f.Clear(Globe.CLEAR); // 重绘标记层 g_f.DrawImage(Globe.SELECTED, Globe.I2C(x), Globe.I2C(y)); // 重绘 Draw(); } }
/// <summary> /// 评价一个棋面上的一方 /// </summary> /// <param name="state">状态</param> /// <param name="type">评价方</param> /// <returns></returns> public int evaluateState(ChessBoard state, int type) { int value = 0; // 线状态 int[][] line = new int[6][]; line[0] = new int[17]; line[1] = new int[17]; line[2] = new int[17]; line[3] = new int[17]; line[4] = new int[17]; line[5] = new int[17]; int lineP; // 方便检查边界 for (int p = 0; p < 6; ++p) { line[p][0] = line[p][16] = Globe.EVA_OP; } // 从四个方向产生 for (int i = 0; i < Globe.BOARD_SIZE; ++i) { // 产生线状态 lineP = 1; for (int j = 0; j < Globe.BOARD_SIZE; ++j) { line[0][lineP] = Globe.getPieceType(state.chessBoard, i, j, type); // | line[1][lineP] = Globe.getPieceType(state.chessBoard, j, i, type); // - line[2][lineP] = Globe.getPieceType(state.chessBoard, i + j, j, type); // \ line[3][lineP] = Globe.getPieceType(state.chessBoard, i - j, j, type); // / line[4][lineP] = Globe.getPieceType(state.chessBoard, j, i + j, type); // \ line[5][lineP] = Globe.getPieceType(state.chessBoard, Globe.BOARD_SIZE - j - 1, i + j, type); // / ++lineP; } // 评估线状态 int special = i == 0 ? 4 : 6; for (int p = 0; p < special; ++p) { value += evaluateLine(line[p], true); } } return(value); }
/// <summary> /// 玩家还是电脑先手 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void PFirstToolStripMenuItem_Click(object sender, EventArgs e) { PFirstToolStripMenuItem.Checked = !PFirstToolStripMenuItem.Checked; PVCStartToolStripMenuItem_Click(null, null); if (PFirstToolStripMenuItem.Checked == false) { Point AIPiece = game.getStartStep(); // AI行棋 if (game.placePiece(AIPiece.X, AIPiece.Y)) { // 绘制棋子 DrawPiece(Globe.USER_1, AIPiece.X, AIPiece.Y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(AIPiece.X), Globe.I2C(AIPiece.Y)); // 绘制落子标记 // 重绘 Draw(); } } }
/// <summary> /// 处理服务器信息 /// </summary> private void ReceiveData() { string receiveString = null; while (isExit == false) { try { //从网络流中读出字符串 //此方法会自动判断字符串长度前缀,并根据长度前缀读出字符串 receiveString = br.ReadString(); } catch { if (isExit == false) { MessageBox.Show("与服务器失去连接"); } break; } string[] splitString = receiveString.Split(','); string command = splitString[0].ToLower(); switch (command) { case "login": //格式: login,用户名 AddOnline(splitString[1]); break; case "logout": //格式: logout,用户名 RemoveUserName(splitString[1]); break; case "start": //格式: start,用户名 DialogResult dr = MessageBox.Show(string.Format("{0}想要和你对弈!", splitString[1]), "", MessageBoxButtons.OKCancel); if (dr == DialogResult.OK) { SendMessage(string.Format("OK,{0}", splitString[1])); model = Globe.PVP; game.startGame(false); // 开始游戏 g_b.Clear(Globe.CLEAR); // 清理磁盘 g_p.Clear(Globe.CLEAR); // 清理落子标记 Draw(); // 重绘 waitForRival = false; rivalName = splitString[1]; orderTogo = false; } else { SendMessage(string.Format("No,{0}", splitString[1])); } break; case "ok": model = Globe.PVP; //人人模式 game.startGame(true); // 开始游戏 g_b.Clear(Globe.CLEAR); // 清理磁盘 g_p.Clear(Globe.CLEAR); // 清理落子标记 Draw(); // 重绘 waitForRival = true; orderTogo = true; break; case "no": MessageBox.Show("对方拒绝和你对弈!"); break; case "step": //MessageBox.Show("sasasa"); int x = Int32.Parse(splitString[1]); int y = Int32.Parse(splitString[2]); game.changeUser(); int curUserNet = game.getCurUser(); // 获取当前行棋人 // 单机模式 // 放置棋子 if (game.placePieceNet(x, y)) { DrawPiece(curUserNet, x, y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(x), Globe.I2C(y)); // 绘制落子标记 Draw(); game.changeUser(); waitForRival = true; } break; case "lose": //格式: talk,用户名 MessageBox.Show("您输了!", "游戏结束", MessageBoxButtons.OK); game.startGame((game.getCurUser() == Globe.USER_1) ? true : false); g_b.Clear(Globe.CLEAR); // 清理磁盘 g_p.Clear(Globe.CLEAR); // 清理落子标记 Draw(); // 重绘 waitForRival = false; break; default: //AddTalkMessage("什么意思啊:" + receiveString); break; } } }
/// <summary> /// 放置棋子 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void chessBoard_MouseDown(object sender, MouseEventArgs e) { // 游戏开始时有效 if (!game.isOver()) { // 取得横纵索引 int x = Globe.C2I(e.X); int y = Globe.C2I(e.Y); //****// if (model == Globe.PVC) //人机 { //****// int curUser = game.getCurUser(); // 获取当前行棋人 // 单机模式 // 放置棋子 if (game.placePiece(x, y)) { if (PFirstToolStripMenuItem.Checked) //玩家先手 { // 绘制棋子 DrawPiece(curUser, x, y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(x), Globe.I2C(y)); // 绘制落子标记 // 重绘 Draw(); int value = 0; value = game.evaluateState(game.curState, curUser); ; // 判断输赢 if (game.isOver()) { string info = "执黑棋方"; if (MessageBox.Show(info + "获胜!\n点击确认开始新游戏", "游戏结束", MessageBoxButtons.OKCancel) == DialogResult.OK ) { PVCStartToolStripMenuItem_Click(null, null); } return; } curUser = game.getCurUser(); Point AIPiece = game.placePieceAI(); // AI行棋 // 绘制棋子 DrawPiece(curUser, AIPiece.X, AIPiece.Y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(AIPiece.X), Globe.I2C(AIPiece.Y)); // 绘制落子标记 // 重绘 Draw(); // 判断输赢 if (game.isOver()) { string info = "执白棋方"; if (MessageBox.Show(info + "获胜!\n点击确认开始新游戏", "游戏结束", MessageBoxButtons.OKCancel) == DialogResult.OK ) { PVCStartToolStripMenuItem_Click(null, null); } } } else //AI先 { curUser = game.getCurUser(); DrawPiece(curUser, x, y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(x), Globe.I2C(y)); // 绘制落子标记 // 重绘 Draw(); if (game.isOver()) { string info = "执白棋方"; if (MessageBox.Show(info + "获胜!\n点击确认开始新游戏", "游戏结束", MessageBoxButtons.OKCancel) == DialogResult.OK ) { PVCStartToolStripMenuItem_Click(null, null); if (PFirstToolStripMenuItem.Checked == false) { Point AIPiece1 = game.getStartStep(); // AI行棋 if (game.placePiece(AIPiece1.X, AIPiece1.Y)) { // 绘制棋子 DrawPiece(Globe.USER_1, AIPiece1.X, AIPiece1.Y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(AIPiece1.X), Globe.I2C(AIPiece1.Y)); // 绘制落子标记 // 重绘 Draw(); } } } return; } Point AIPiece = game.placePieceAI(); // AI行棋 curUser = game.getCurUser(); DrawPiece(Globe.USER_1, AIPiece.X, AIPiece.Y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(AIPiece.X), Globe.I2C(AIPiece.Y)); // 绘制落子标记 // 重绘 Draw(); if (game.isOver()) { string info = "执黑棋方"; if (MessageBox.Show(info + "获胜!\n点击确认开始新游戏", "游戏结束", MessageBoxButtons.OKCancel) == DialogResult.OK ) { PVCStartToolStripMenuItem_Click(null, null); if (PFirstToolStripMenuItem.Checked == false) { Point AIPiece2 = game.getStartStep(); // AI行棋 if (game.placePiece(AIPiece2.X, AIPiece2.Y)) { // 绘制棋子 DrawPiece(Globe.USER_1, AIPiece2.X, AIPiece2.Y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(AIPiece2.X), Globe.I2C(AIPiece2.Y)); // 绘制落子标记 // 重绘 Draw(); } } } return; } } } } else if (model == Globe.PVP)// 网络模式 { //MessageBox.Show("sasasa"); int curUserNet = game.getCurUser(); // 获取当前行棋人 // 单机模式 // 放置棋子 if (waitForRival && game.placePieceNet(x, y)) //短路与 重要 placePieceNet会改变棋盘信息 { DrawPiece(curUserNet, x, y); // 绘制落子标记 g_p.Clear(Globe.CLEAR); // 重绘落子标记 g_p.DrawImage(Globe.SET, Globe.I2C(x), Globe.I2C(y)); // 绘制落子标记 Draw(); SendMessage(string.Format("Step,{0},{1},{2}", rivalName, x.ToString(), y.ToString())); waitForRival = false; } int value = 0; value = game.evaluateState(game.curState, curUserNet); // 判断输赢 if (game.isOver()) { SendMessage("Lose," + rivalName); if (MessageBox.Show("恭喜你赢了!", "游戏结束", MessageBoxButtons.OK) == DialogResult.OK ) { game.startGame((curUserNet == Globe.USER_1) ? true : false); g_b.Clear(Globe.CLEAR); // 清理磁盘 g_p.Clear(Globe.CLEAR); // 清理落子标记 Draw(); // 重绘 waitForRival = true; } return; } } } }
/// <summary> /// 对一个状态的一个位置 /// 放置一种类型的棋子的优劣进行估价 /// </summary> /// <param name="state">状态</param> /// <param name="x">位置的横坐标</param> /// <param name="y">位置的纵坐标</param> /// <param name="type">棋子的类型</param> /// <returns>评估值</returns> private int evaluatePiece(ChessBoard state, int x, int y, int type) { int value = 0; // 估价值 int[] line = new int[17]; // 线状态 bool[] flagX = new bool[8]; // 横向边界标志 flagX[0] = x - 4 < 0; flagX[1] = x - 3 < 0; flagX[2] = x - 2 < 0; flagX[3] = x - 1 < 0; flagX[4] = x + 1 > 14; flagX[5] = x + 2 > 14; flagX[6] = x + 3 > 14; flagX[7] = x + 4 > 14; bool[] flagY = new bool[8]; // 纵向边界标志 flagY[0] = y - 4 < 0; flagY[1] = y - 3 < 0; flagY[2] = y - 2 < 0; flagY[3] = y - 1 < 0; flagY[4] = y + 1 > 14; flagY[5] = y + 2 > 14; flagY[6] = y + 3 > 14; flagY[7] = y + 4 > 14; line[4] = Globe.EVA_MY; // 设置中心棋子 // 横 line[0] = flagX[0] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x - 4, y].type, type)); line[1] = flagX[1] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x - 3, y].type, type)); line[2] = flagX[2] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x - 2, y].type, type)); line[3] = flagX[3] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x - 1, y].type, type)); line[5] = flagX[4] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x + 1, y].type, type)); line[6] = flagX[5] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x + 2, y].type, type)); line[7] = flagX[6] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x + 3, y].type, type)); line[8] = flagX[7] ? Globe.EVA_OP : (Globe.getPieceType(state.chessBoard[x + 4, y].type, type)); value += evaluateLine(line); // 纵 line[0] = flagY[0] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y - 4].type, type); line[1] = flagY[1] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y - 3].type, type); line[2] = flagY[2] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y - 2].type, type); line[3] = flagY[3] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y - 1].type, type); line[5] = flagY[4] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y + 1].type, type); line[6] = flagY[5] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y + 2].type, type); line[7] = flagY[6] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y + 3].type, type); line[8] = flagY[7] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x, y + 4].type, type); value += evaluateLine(line); // 左上-右下 line[0] = flagX[0] || flagY[0] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 4, y - 4].type, type); line[1] = flagX[1] || flagY[1] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 3, y - 3].type, type); line[2] = flagX[2] || flagY[2] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 2, y - 2].type, type); line[3] = flagX[3] || flagY[3] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 1, y - 1].type, type); line[5] = flagX[4] || flagY[4] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 1, y + 1].type, type); line[6] = flagX[5] || flagY[5] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 2, y + 2].type, type); line[7] = flagX[6] || flagY[6] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 3, y + 3].type, type); line[8] = flagX[7] || flagY[7] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 4, y + 4].type, type); value += evaluateLine(line); // 右上-左下 line[0] = flagX[7] || flagY[0] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 4, y - 4].type, type); line[1] = flagX[6] || flagY[1] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 3, y - 3].type, type); line[2] = flagX[5] || flagY[2] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 2, y - 2].type, type); line[3] = flagX[4] || flagY[3] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x + 1, y - 1].type, type); line[5] = flagX[3] || flagY[4] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 1, y + 1].type, type); line[6] = flagX[2] || flagY[5] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 2, y + 2].type, type); line[7] = flagX[1] || flagY[6] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 3, y + 3].type, type); line[8] = flagX[0] || flagY[7] ? Globe.EVA_OP : Globe.getPieceType(state.chessBoard[x - 4, y + 4].type, type); value += evaluateLine(line); return(value); }