C语言实现简单的五子棋
#define _CRT_SECURE_NO_WARNINGS 1
#define __STDC_WANT_LIB_EXT1_ 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
//┌ ┬ ┐├ ┼ ┤└ ┴ ┘│─●○
//属性设置:0—白棋 1—黑棋 2—无棋
int board[20][20];//注意这个二维数组为全局更方便
int Board(int row, int column, int player, int cover, int remind);//row横向,column竖向,player为玩家代号
void operation(); //操作棋子的函数(主要) //cover为检测棋子重叠的参数,remind是输赢提示
int judge(char, int, int, int, int);//判断操作是移动还是回车,检测棋子重叠
int rule(int, int, int); //判断输赢,棋子算法
void menu(); //菜单
int main()
{ //em。。我这个main函数似乎过于简洁?
menu(); //这也看出本程序的各个函数独立性不是很高
operation();
return 0;
}
void menu()
{
char ch;
loop1:
system("cls");
printf("\n\n\n\n\n\n\n");
for (int i = 0; i < 2; i++)
printf(" ************************* \n");
printf(" * ★和轩来玩五子棋★ * \n");
printf(" * 1.开始游戏 * \n");
printf(" * 2.退出游戏 * \n");
printf(" * 3.游戏帮助 * \n");
printf(" * ★ ★ ★ ★ ★ * \n");
printf(" ************************* \n");
ch = getch();
if(ch=='1')
{ }
else if(ch == '2')
{
system("cls");
printf("\n\n\n\n\n\n\n");
printf(" ************************* \n");
printf(" * ★和轩来玩五子棋★ * \n");
printf(" * 再见! * \n");
printf(" * ★ ★ ★ ★ ★ * \n");
printf(" ************************* \n");
exit(1);
}
else if (ch == '3')
{
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n\n\n");
printf(" *****************************************************\n");
printf(" * 操作方法:←↑↓→移动棋子,回车放棋. *\n");
printf(" * 游戏声明:本游戏仅支持玩家对战,人机模式敬请期待 *\n");
printf(" * (快打赏轩哥催更吧(づ ̄3 ̄)づ╭~) *\n");
printf(" * *\n");
printf(" * 按空格返回菜单 *\n");
printf(" *****************************************************\n");
if (getch() == 32)
goto loop1;
else
{
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n\n\n");
printf(" 输入错误,请重新输入!");
Sleep(3000);
goto loop1;
}
}
}
int Board(int row, int column, int player, int If_cover, int remind)
{
printf("\n\n\n\n");
//注意!本棋盘是每一次操作后重新打印的棋盘,是动态的,而不是三子棋那样的死棋盘
//边界和角落特殊处理!而且打印必须按顺序!从上往下!否则打印出来会乱七八糟!注意!每个图标后面都有空格,否则重叠
//下面为左上角
switch (board[0][0])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("┌ ");
break;
}
//下面为上边界
for (int i = 1; i < 19; i++)
{
switch (board[0][i])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("┬ ");
break;
}
}
//下面为右上角
switch (board[0][19])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("┐");
break;
}
printf("\n");
//下面为第1排到第18排(前面是第0排)
for (row = 1; row < 19; row++)
{
//下面是特殊处理左边界
switch (board[row][0])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("├ ");
break;
}
//下面是打印十字
for (column = 1; column < 19; column++)
{
switch (board[row][column])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("┼ ");
break;
}
}
//下面是打印右边界
switch (board[row][19])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("┤ ");
break;
}
if (row == 8)
printf(" ************************************** ");
if (row == 9)
printf(" * * ");
if (row == 10)
printf(" *操作方法:←↑↓→移动棋子,回车放棋*");
if (row == 11 || row == 12)
printf(" * *");
if (row == 13)
{
if (If_cover == 1)
printf(" *提示:此处已有棋子,请选择其他位置: *");
else if (remind == 1)
{
printf("\a *提示: 玩家1获胜! *");
}
else if (remind == 2)
{
printf("\a *提示: 玩家2获胜! *");
}
else
printf(" *提示: 玩家%d请下棋 *", player == 1 ? 1 : 2);
}
if (row == 14)
{
if ((remind == 1) || (remind == 2))
printf(" *按空格键重新开局,否则结束游戏! *");
else
printf(" * *");
}
if (row == 15)
{
printf(" **************************************");
}
printf("\n");
}
//下面是打印19排左下角
switch (board[19][0])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("└ ");
break;
}
//下面为下边界
for (int i = 1; i < 19; i++)
{
switch (board[19][i])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("┴ ");
break;
}
}
//下面为右下角
switch (board[19][19])
{
case 0:printf("○");
break;
case 1:printf("●");
break;
case 2:printf("┘ ");
break;
}
printf("\n");
if ((remind == 1) || (remind == 2))
{
if (getch() == 32)
return 2;
}
}
void operation()
{
loop:
//初始化棋盘
for (int count = 0; count < 400; count++)
*(*board + count) = 2;
int player;
int Judge = 0;
int remind = 0;
int row = 0, column = 0;
for (int count = 1; count <= 400; count++)
{
player = count % 2;
if (count == 1)
{
board[0][0] = 0;
system("cls");
Board(row, column, count, Judge, remind);
board[0][0] = 2; //使初始化的棋盘左上角有一个棋子,从此处开始移动棋子
}
//下面是移动棋子的操作 上下左右键对应ASCII码值: 72-up 80-down 75-left 77-right
int k = 1; //用作下面退出while
int copy = 0;
char move;
int If_cover = 0;
while (k)
{
move = getch();
switch (move)
{
case 75:
system("cls");
column = column - 1;
if (column < 0)
column = 19;
copy = board[row][column];
board[row][column] = (player == 1 ? 0 : 1);
If_cover = 0;
Board(row, column, player, If_cover, remind);
judge(move, row, column, player, copy);
break;
case 77:
system("cls");
column = column + 1;
if (column > 19)
column = 0;
copy = board[row][column];
board[row][column] = (player == 1 ? 0 : 1);
If_cover = 0;
Board(row, column, player, If_cover, remind);
judge(move, row, column, player, copy);
break;
case 80:
system("cls");
row = row + 1;
if (row > 19)
row = 0;
copy = board[row][column];
board[row][column] = (player == 1 ? 0 : 1);
If_cover = 0;
Board(row, column, player, If_cover, remind);
judge(move, row, column, player, copy);
break;
case 72:
system("cls");
row = row - 1;
if (row < 0)
row = 19;
copy = board[row][column];
board[row][column] = (player == 1 ? 0 : 1);
If_cover = 0;
Board(row, column, player, If_cover, remind);
judge(move, row, column, player, copy);
break;
case 13:
Judge = judge(move, row, column, player, copy);
if (Judge == 1)
{
If_cover = 1;
system("cls");
Board(row, column, player, If_cover, remind);
continue;
}
remind = rule(row, column, player);
if ((remind == 2) || (remind == 1))
{
int k = 0;
system("cls");
k = Board(row, column, player, If_cover, remind);
if (k == 2)
{
goto loop;
}
else
{
system("cls");
printf("\n\n\n\n\n\n\n");
printf(" ************************* \n");
printf(" * ★和轩来玩五子棋★ * \n");
printf(" * 再见! * \n");
printf(" * ★ ★ ★ ★ ★ * \n");
printf(" ************************* \n");
exit(1);
}
}
int copy_player = player;
if (copy_player == 1) //下面6行代码是为了使按回车放棋后能够马上同步提示,而不是继续移动后才更新!
copy_player = 0;
else
copy_player = 1;
system("cls");
Board(row, column, copy_player, If_cover, remind);
k = 0; //k=0终止while循环!注意下面的break是终止switch的!
break;
}
}
}
}
int judge(char move, int row, int column, int player, int copy) //此函数是用来判断是移步还是定步,是否重叠
{
if (move == 72 || move == 75 || move == 77 || move == 80)
{
if ((board[row][column] == 1) || (board[row][column] == 0)) //这是为了使移动棋子时如果压到已下的棋子,可以防止被覆盖属性
{
board[row][column] = copy; //只要不回车,就保持原属性不变!
}
else
board[row][column] = 2;
}
if (move == 13) //检测到回车
{
if (board[row][column] == 2) //如果此处是空,则放棋
board[row][column] = (player == 1 ? 0 : 1);
else
{
return 1; //不空,返回1,提示有棋子了,重新选择
}
}
}
int rule(int row, int column, int player)
{
if (player == 1)
{
//横向检查player1
int copy_row = row;
int copy_column = column;
int tem_association1 = 0;
for (copy_column = 0; copy_column < 20; copy_column++)
{
if (board[row][copy_column] == 0)
{
tem_association1++;
}
if (board[row][copy_column] != 0)
{
tem_association1 = 0;
}
if (tem_association1 == 5)
{
return 1;
}
}
//竖向检测player1
copy_row = row;
copy_column = column;
tem_association1 = 0;
for (copy_row = 0; copy_row < 20; copy_row++)
{
if (board[copy_row][column] == 0)
tem_association1++;
if (board[copy_row][column] != 0)
tem_association1 = 0;
if (tem_association1 == 5)
{
return 1;
}
}
//斜向1处理player1 //这个斜向检测算法只需最多检测8个位置
int count1 = 0, count2 = 0, counts = 0; // *
for (count1 = 1; count1 <= 5;) // *
{ // *
if ((row == 0) || (column == 0)) //起始在边界则中断 // *
break; // # 从#向两边检测,遇到非本方棋子则中断,满4则赢
if (((row - count1) == 0) || ((column - count1) == 0)) // * 每次斜向检测分为两部分,一是向左上(右上),二是向右下(左下)
{ // *
if (board[row - count1][column - count1] == 0) // *
{ // *
count1++;
break;
}
else
break;
}
else
{
if (board[row - count1][column - count1] == 0)
{
count1++;
continue;
}
else
break;
}
}
//斜向2处理player1
for (count2 = 1; count2 <= 5;)
{
if ((row == 19) || (column == 19))
break;
if (((row + count2) == 19) || ((column + count2) == 19))
{
if (board[row + count2][column + count2] == 0)
{
count2++;
break;
}
else
break;
}
else
{
if (board[row + count2][column + count2] == 0)
{
count2++;
continue;
}
else
break;
}
}
counts = count1 + count2 - 2;
if (counts >= 4)
{
return 1;
}
//斜向2处理玩家1
count1 = 0, count2 = 0, counts = 0;
for (count1 = 1; count1 <= 5;)
{
if ((row == 0) || (column == 19))
break;
if (((row - count1) == 0) || ((column + count1) == 0))
{
if (board[row - count1][column + count1] == 0)
{
count1++;
break;
}
else
break;
}
else
{
if (board[row - count1][column + count1] == 0)
{
count1++;
continue;
}
else
break;
}
}
for (count2 = 1; count2 <= 5;)
{
if ((row == 19) || (column == 0))
break;
if (((row + count2) == 19) || ((column - count2) == 0))
{
if (board[row + count2][column - count2] == 0)
{
count2++;
break;
}
else
break;
}
else
{
if (board[row + count2][column - count2] == 0)
{
count2++;
continue;
}
else
break;
}
}
counts = count1 + count2 - 2;
if (counts >= 4)
{
return 1;
}
}
if (player == 0)
{
//横向检查player2
int copy_row = row;
int copy_column = column;
int tem_association2 = 0;
for (copy_column = 0; copy_column < 20; copy_column++)
{
if (board[row][copy_column] == 1)
{
tem_association2++;
}
if (board[row][copy_column] != 1)
{
tem_association2 = 0;
}
if (tem_association2 == 5)
{
return 2;
}
}
//竖向检测player2
copy_row = row;
copy_column = column;
tem_association2 = 0;
for (copy_row = 0; copy_row < 20; copy_row++)
{
if (board[copy_row][column] == 1)
tem_association2++;
if (board[copy_row][column] != 1)
tem_association2 = 0;
if (tem_association2 == 5)
{
return 2;
}
}
//斜向1处理player2
int count1 = 0, count2 = 0, counts = 0;
for (count1 = 1; count1 <= 5;)
{
if ((row == 0) || (column == 0))
break;
if (((row - count1) == 0) || ((column - count1) == 0))
{
if (board[row - count1][column - count1] == 1)
{
count1++;
break;
}
else
break;
}
else
{
if (board[row - count1][column - count1] == 1)
{
count1++;
continue;
}
else
break;
}
}
for (count2 = 1; count2 <= 5;)
{
if ((row == 19) || (column == 19))
break;
if (((row + count2) == 19) || ((column + count2) == 19))
{
if (board[row + count2][column + count2] == 1)
{
count2++;
break;
}
else
break;
}
else
{
if (board[row + count2][column + count2] == 1)
{
count2++;
continue;
}
else
break;
}
}
counts = count1 + count2 - 2;
if (counts >= 4)
{
return 2;
}
//斜向2处理玩家2
count1 = 0, count2 = 0, counts = 0;
for (count1 = 1; count1 <= 5;)
{
if ((row == 0) || (column == 19))
break;
if (((row - count1) == 0) || ((column + count1) == 0))
{
if (board[row - count1][column + count1] == 1)
{
count1++;
break;
}
else
break;
}
else
{
if (board[row - count1][column + count1] == 1)
{
count1++;
continue;
}
else
break;
}
}
for (count2 = 1; count2 <= 5;)
{
if ((row == 19) || (column == 0))
break;
if (((row + count2) == 19) || ((column - count2) == 0))
{
if (board[row + count2][column - count2] == 1)
{
count2++;
break;
}
else
break;
}
else
{
if (board[row + count2][column - count2] == 1)
{
count2++;
continue;
}
else
break;
}
}
counts = count1 + count2 - 2;
if (counts >= 4)
{
return 2;
}
}
return 3; //必须要return 非1或2的数,否则会默认return 1
}
容错性相对较高,仅支持玩家对战

浙公网安备 33010602011771号