#include <stdio.h>
#include <conio.h>
#include <windows.h>
/***x是光标的横坐标,y是光标的纵坐标,flag用于切换黑白棋,over判断游戏是否结束。***/
int x = 9, y = 9, flag = 0, over = 0, peace = 361, reChessboard[19][20] = {0};
/***定义符号集***/
char *symbol[] = {"", "●", "○", "┬ ", "┴ ", "├ ", "┤ ", "┼ ", "┌ ", "┐ ", "└ ", "┘ ", "\n"};
/***定义19行22列的棋盘,每行前19列保存棋盘信息,后三行保存其他字符信息以及换行符***/
int Chessboard[19][20] = {{8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 9, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 12},
{10,4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 11, 0}};
/***备份棋盘,用于重新开始后恢复棋盘的初始状态***/
void backup() {
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 20; j++) {
reChessboard[i][j] = Chessboard[i][j];
}
}
}
/***绘制棋盘函数***/
void drawBoard() {
system("cls");//清屏函数,属于Dos命令。
//通过循环绘制出棋盘。
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 20; j++) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
(i == x && j == y) ? ((Chessboard[i][j] != 1 && Chessboard[i][j] != 2 && over != 1)
? 175 : 207)
: 15);//绘制光标
printf("%s", symbol[Chessboard[i][j]]);//取出符号集里的符号并拼凑成棋盘。
}
}
}
/***重新开始函数***/
void restart() {
//通过循环将棋盘恢复至初始状态
for (int i = 0; i < 19; i++) {
for (int j = 0; j < 20; j++) {
Chessboard[i][j] = reChessboard[i][j];
}
}
//重置变量的值
x = 9;
y = 9;
flag = 0;
over = 0;
peace = 361;
drawBoard();//重新绘制棋盘
}
/***判断输赢函数***/
void judge() {
drawBoard();
if (peace <= 0) {
MessageBox(NULL, "平局", "游戏结束", 0);
over = 1;
}
int a, b, m = x, n = y, totalH = 1, totalS = 1, totalN = 1, totalP = 1;
//判断垂直方向的连子数量,连子数量大于等于5个则游戏结束。
for (a = m - 1; a >= 0; a--) {
if (Chessboard[a][n] == Chessboard[m][n]) {
totalS++;
} else {
break;
}
}
for (a = m + 1; a <= 18; a++) {
if (Chessboard[a][n] == Chessboard[m][n]) {
totalS++;
} else {
break;
}
}
if (totalS >= 5) {
MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
over = 1;
}
//判断水平方向的连子数量,连子数量大于等于5个则游戏结束。
for (b = n - 1; b >= 0; b--) {
if (Chessboard[m][b] == Chessboard[m][n]) {
totalH++;
} else {
break;
}
}
for (b = n + 1; b <= 18; b++) {
if (Chessboard[m][b] == Chessboard[m][n]) {
totalH++;
} else {
break;
}
}
if (totalH >= 5) {
MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
over = 1;
}
//判断左上-右下方向的连子数量,连子数量大于等于5个则游戏结束。
for (a = m - 1, b = n - 1; a >= 0 || b >= 0; a--, b--) {
if (Chessboard[a][b] == Chessboard[m][n]) {
totalN++;
} else {
break;
}
}
for (a = m + 1, b = n + 1; a <= 18 || b <= 18; a++, b++) {
if (Chessboard[a][b] == Chessboard[m][n]) {
totalN++;
} else {
break;
}
}
if (totalN >= 5) {
MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
over = 1;
}
//判断左下-右上方向的连子数量,连子数量大于等于5个则游戏结束。
for (a = m - 1, b = n + 1; a >= 0 || b <= 18; a--, b++) {
if (Chessboard[a][b] == Chessboard[m][n]) {
totalP++;
} else {
break;
}
}
for (a = m + 1, b = n - 1; a <= 18 || b >= 0; a++, b--) {
if (Chessboard[a][b] == Chessboard[m][n]) {
totalP++;
} else {
break;
}
}
if (totalP >= 5) {
MessageBox(NULL, Chessboard[m][n] == 1 ? "白棋获胜" : "黑棋获胜", "游戏结束", 0);
over = 1;
}
}
/***AI函数***/
void ai() {
if (over != 1) {
}
}
/***按键监听函数***/
void monitor() {
int keyValue;
while ((keyValue = getch()) != 0x1B) {//当按下ESC时程序退出
if (keyValue == 119 || keyValue == 87 || keyValue == 72) { //W,w,↑向上
x >= 1 ? x-- : (x = 0);//防止光标越界
} else if (keyValue == 115 || keyValue == 83 || keyValue == 80) {//S,s,↓向下
x <= 17 ? x++ : (x = 18);//防止光标越界
} else if (keyValue == 97 || keyValue == 75 || keyValue == 65) {//A,a,←向左
y >= 1 ? y-- : (y = 0);//防止光标越界
} else if (keyValue == 100 || keyValue == 77 || keyValue == 68) {//D,d,→向右
y <= 17 ? y++ : (y = 18);//防止光标越界
} else if (keyValue == 114 || keyValue == 82) {//R键重新开始
restart();//重新开始
} else if (keyValue == 32 || keyValue == 13) {//空格或回车落子
if (Chessboard[x][y] != 1 && Chessboard[x][y] != 2 && over == 0) {//切换黑白棋
Chessboard[x][y] = flag % 2 == 0 ? 1 : 2;
flag++;
peace--;
judge();//判断连子
}
}
drawBoard();
}
}
/***主函数***/
int main() {
backup();
system("mode con cols=38 lines=19");//设置DOS窗口大小
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &(CONSOLE_CURSOR_INFO) {25});//隐藏DOS自带光标
drawBoard();//绘制棋盘
monitor();//按键监听
}