【C++/控制台】简易五子棋游戏
程序源码:
#include <iostream>
#include <vector>
#include <string>
#include <windows.h>
using namespace std;void color(int x) {// 设置颜色的函数if (x >= 0 & x <= 15)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);else {SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);}
}class Chess {
public:int a[15][15];Chess();void paint1();void play();int AI();int player(int, int, int);int max1(int a1[4]);int get1(int a1[4]);int s;int s1[2];
};Chess::Chess() {// 棋盘类的构造函数for (int i = 0; i < 15; i++) {for (int j = 0; j < 15; j++) {a[i][j] = 0;}}s = 0;s1[0] = -1;s1[1] = -1;
}int Chess::max1(int a1[4]) {int temp = a1[0];for (int i = 1; i < 4; i++)if (a1[i] > temp) {temp = a1[i];}return temp;
}int Chess::get1(int a1[4]) {int temp = a1[0];int tp1 = 1;for (int i = 1; i < 4; i++)if (a1[i] > temp) {temp = a1[i];tp1 = i + 1;}return tp1;
}void Chess::paint1() {// 绘制棋盘的函数cout << " ";for (int i = 0; i < 15; i++) {if (i <= 9) {cout << i << " ";} elsecout << i << "";}cout << endl;for (int i = 0; i < 15; i++) {if (i <= 9) {cout << i << " ";} elsecout << i << " ";for (int j = 0; j < 15; j++) {if (a[i][j] == 0) {color(7);cout << "十";} else if (a[i][j] == 1) {color(12); // 显示红色棋子cout << "红";} else if (a[i][j] == 2) {color(2); // 显示蓝色棋子cout << "蓝";}}cout << endl;}
}int Chess::player(int x1, int y1, int z) {if (a[x1][y1] != 0) {cout << "落子无效";return 1;}a[x1][y1] = z;// 判断同一直线上位置是否有五子int total = 0;for (int i = y1 - 1; i >= 0; i--) {if (a[x1][i] == z)total++;elsebreak;}for (int i = y1 + 1; i < 15; i++) {if (a[x1][i] == z)total++;elsebreak;}if (total >= 4)return 5; // 获胜// 判断同一竖线上是否有五子total = 0;for (int i = x1 - 1; i >= 0; i--) {if (a[i][y1] == z)total++;elsebreak;}for (int i = x1 + 1; i < 15; i++) {if (a[i][y1] == z)total++;elsebreak;}if (total >= 4)return 5; // 获胜// 判断左斜线是否有五子total = 0;for (int i = 1; i < 5; i++) {if (x1 - i < 0 || y1 - i < 0)break;if (a[x1 - i][y1 - i] == z)total++;elsebreak;}for (int i = 1; i < 5; i++) {if (x1 + i >= 15 || y1 + i >= 15)break;if (a[x1 + i][y1 + i] == z)total++;elsebreak;}if (total >= 4)return 5; // 获胜// 判断右斜线是否有五子;total = 0;for (int i = 1; i < 5; i++) {if (x1 - i < 0 || y1 + i >= 15)break;if (a[x1 - i][y1 + i] == z)total++;elsebreak;}for (int i = 1; i < 5; i++) {if (x1 + i >= 15 || y1 - i < 0)break;if (a[x1 + i][y1 - i] == z)total++;elsebreak;}if (total >= 4)return 5; // 获胜return 2; // 落子有效,但未获胜
}int Chess::AI() {int t1 = 0;// 判断自己有没有四子的情况for (int i = 0; i < 15; i++) {for (int j = 0; j < 15; j++) {int total1 = 0;int total2 = 0;int total3 = 0;int total4 = 0;if (a[i][j] != 0)continue;for (int a1 = 1; a1 < 5; a1++) {// 判断水平线if (j - a1 < 0)break;if (a[i][j - a1] == 2)total1++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (j + a1 >= 15)break;if (a[i][j + a1] == 2)total1++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断竖直部分if (i - a1 < 0)break;if (a[i - a1][j] == 2)total2++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15)break;if (a[i + a1][j] == 2)total2++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断左斜线if (i - a1 < 0 || j - a1 < 0)break;if (a[i - a1][j - a1] == 2)total3++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15 || j + a1 >= 15)break;if (a[i + a1][j + a1] == 2)total3++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断右斜线if (i - a1 < 0 || j + a1 >= 15)break;if (a[i - a1][j + a1] == 2)total4++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15 || j - a1 < 0)break;if (a[i + a1][j - a1] == 2)total4++;elsebreak;}int a1[4] = {total1, total2, total3, total4};int temp = max1(a1);if (temp >= 4) {a[i][j] = 2;// cout<<"AI已获胜";return -1;}}}for (int i = 0; i < 15; i++) {// 判断对手是否有大于三子的情况for (int j = 0; j < 15; j++) {int total1 = 0;int total2 = 0;int total3 = 0;int total4 = 0;if (a[i][j] == 1 || a[i][j] == 2)continue;for (int a1 = 1; a1 < 5; a1++) {// 判断水平线if (j - a1 < 0)break;if (a[i][j - a1] == 1)total1++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (j + a1 >= 15)break;if (a[i][j + a1] == 1)total1++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断竖直线if (i - a1 < 0)break;if (a[i - a1][j] == 1)total2++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15)break;if (a[i + a1][j] == 1)total2++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断左斜线if (i - a1 < 0 || j - a1 < 0)break;if (a[i - a1][j - a1] == 1)total3++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15 || j + a1 >= 15)break;if (a[i + a1][j + a1] == 1)total3++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断右斜线if (i - a1 < 0 || j + a1 >= 15)break;if (a[i - a1][j + a1] == 1)total4++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15 || j - a1 < 0)break;if (a[i + a1][j - a1] == 1)total4++;elsebreak;}int a1[4] = {total1, total2, total3, total4};int temp = max1(a1);int tp1 = get1(a1); // 获取哪个方向上连子最多,1表示水平线,2代表竖直线,3代表左斜线,4代表右斜线if (temp == 3) {// 对手已经三子,此时要分情况,有边界的三子不用堵,没有边界的三子需要堵if (tp1 == 1) {// 水平线有三子int a1;int tpx1 = 0;for (a1 = 1; a1 <= 3; a1++) {// tpx1=0;if (j - a1 < 0)break;if (a[i][j - a1] == 1)tpx1++;elsebreak;}if (tpx1 == 3) {if (j - a1 == 0) {} else if (j - a1 - 1 >= 0) {if (a[i][j - a1 - 1] == 0) {a[i][j] = 2;return 0;}}}else if (tpx1 == 2) {a[i][j] = 2;return 0;} else if (tpx1 == 1) {a[i][j] = 2;return 0;} else if (tpx1 == 0) {if (j + a1 == 14) {} else if (j + a1 < 14) {if (a[i][j + a1 + 1] == 0) {a[i][j] = 2;return 0;}}}} // 水平线三子情况判断结束else if (tp1 == 2) {// 竖直线有三子的情况int a1;int tpx1 = 0;for (a1 = 1; a1 <= 3; a1++) {// tpx1=0;if (i - a1 < 0)break;if (a[i - a1][j] == 1)tpx1++;elsebreak;}if (tpx1 == 3) {if (i - a1 == 0) {} else if (i - a1 - 1 >= 0) {if (a[i - a1 - 1][j] == 0) {a[i][j] = 2;return 0;}}}else if (tpx1 == 2) {a[i][j] = 2;return 0;} else if (tpx1 == 1) {a[i][j] = 2;return 0;} else if (tpx1 == 0) {if (i + a1 == 14) {} else if (i + a1 < 14) {if (a[i + a1 + 1][j] == 0) {a[i][j] = 2;return 0;}}}} // 竖直线有三子情况判断结束else if (tp1 == 3) {// 左斜线有三子的情况int a1;int tpx1 = 0;for (a1 = 1; a1 <= 3; a1++) {// tpx1=0;if (i - a1 < 0 || j - a1 < 0)break;if (a[i - a1][j - a1] == 1)tpx1++;elsebreak;}if (tpx1 == 3) {if (i - a1 == 0 || j - a1 == 0) {} else if (i - a1 - 1 >= 0 and j - a1 - 1 >= 0) {if (a[i - a1 - 1][j - a1 - 1] == 0) {a[i][j] = 2;return 0;}}}else if (tpx1 == 2) {a[i][j] = 2;return 0;} else if (tpx1 == 1) {a[i][j] = 2;return 0;} else if (tpx1 == 0) {if (i + a1 == 14 || j + a1 == 14) {} else if (i + a1 < 14 and j + a1 < 14) {if (a[i + a1 + 1][j + a1 + 1] == 0) {a[i][j] = 2;return 0;}}}} // 左斜线三子情况判断结束else if (tp1 == 4) {// 判断右斜线有三子的情况int a1;int tpx1 = 0;for (a1 = 1; a1 <= 3; a1++) {// tpx1=0;if (i - a1 < 0 || j + a1 > 14)break;if (a[i - a1][j + a1] == 1)tpx1++;elsebreak;}if (tpx1 == 3) {if (i - a1 == 0 || j + a1 == 14) {} else if (i - a1 - 1 >= 0 and j + a1 + 1 <= 14) {if (a[i - a1 - 1][j + a1 + 1] == 0) {a[i][j] = 2;return 0;}}}else if (tpx1 == 2) {a[i][j] = 2;return 0;} else if (tpx1 == 1) {a[i][j] = 2;return 0;} else if (tpx1 == 0) {if (i + a1 == 14 || j - a1 == 0) {} else if (i + a1 < 14 and j - a1 > 0) {if (a[i + a1 + 1][j - a1 - 1] == 0) {a[i][j] = 2;return 0;}}}} // 右斜线三子情况判断结束} // 对手有三子的情况 (if的括号)else if (temp == 4 || temp == 5) {// 对手有四子或五子,一定要堵a[i][j] = 2;return 0;}}}// 判断对手连子情况结束,开始连自己五子for (int i = 0; i < 15; i++) {for (int j = 0; j < 15; j++) {if (a[i][j] == 2)t1++;}}if (t1 == 0) {a[7][7] = 2;return 0;}for (int i = 0; i < 15; i++) {for (int j = 0; j < 15; j++) {int total1 = 0;int total2 = 0;int total3 = 0;int total4 = 0;if (a[i][j] != 0)continue;for (int a1 = 1; a1 < 5; a1++) {// 判断水平线if (j - a1 < 0)break;if (a[i][j - a1] == 2)total1++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (j + a1 >= 15)break;if (a[i][j + a1] == 2)total1++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断竖直部分if (i - a1 < 0)break;if (a[i - a1][j] == 2)total2++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15)break;if (a[i + a1][j] == 2)total2++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断左斜线if (i - a1 < 0 || j - a1 < 0)break;if (a[i - a1][j - a1] == 2)total3++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15 || j + a1 >= 15)break;if (a[i + a1][j + a1] == 2)total3++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {// 判断右斜线if (i - a1 < 0 || j + a1 >= 15)break;if (a[i - a1][j + a1] == 2)total4++;elsebreak;}for (int a1 = 1; a1 < 5; a1++) {if (i + a1 >= 15 || j - a1 < 0)break;if (a[i + a1][j - a1] == 2)total4++;elsebreak;}int a1[4] = {total1, total2, total3, total4};int temp = max1(a1);if (temp >= 4) {a[i][j] = 2;// cout<<"AI已获胜";return -1;}if (temp > s) {s = temp;s1[0] = i;s1[1] = j;}}}s = 0;a[s1[0]][s1[1]] = 2;s1[0] = -1;s1[1] = -1;return 0;
}void Chess::play() {while (1) {int x1, y1;int temp = AI();paint1();cout << endl;if (temp == -1) {cout << "AI已获胜";Sleep(20000);return;}cout << "AI已经落子" << endl;cout << "请红方落子" << endl;cin >> x1 >> y1;temp = player(x1, y1, 1);cout << endl;if (temp == 1) {while (temp == 1) {paint1();cout << "红方落子无效,请重新落子";cin >> x1 >> y1;temp = player(x1, y1, 1);cout << endl;}}if (temp == 5) {paint1();cout << "恭喜红方获胜" << endl;Sleep(20000);return;}paint1();cout << endl;}
}int main() {Chess a;a.paint1();a.play();
}
运行结果: