利用C语言实现五子棋游戏

本文实例为大家分享了C语言实现五子棋游戏的具体代码,供大家参考,具体内容如下

一、前言

本文将先介绍五子棋运行所需要的函数,最后串联成完整代码。

我们需要实现的功能有:1.菜单menu函数

                                        2.初始化棋盘Initboard函数

                                        3.显示棋盘Displayboard函数

                                        4.实现人机、人人模式的选择

                                        5.落子函数 playermove  computermove

                                        6.判断输赢ifwin函数

先来看看运行效果吧!

二、头文件

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#include <string.h>

#include<time.h>

#include<stdlib.h>

#include<windows.h>

#define ROW 10 //定义棋盘的宽

#define COL 10 //定义棋盘的长

//定义常量方便全局的修改

void Initboard(char board[ROW][COL], int row, int col);

//初始化棋盘

void Displayboard(char board[ROW][COL], int row, int col);

//展示棋盘

void Playermove_1(char board[ROW][COL], int row, int col,int*px,int *py);

//玩家一下棋

void Playermove_2(char board[ROW][COL], int row, int col,int*px, int *py);

//玩家二下棋

void computermove(char board[ROW][COL], int row, int col);

//电脑下棋

void game1(char board[ROW][COL], int row, int col);

//人机模式

void game2(char board[ROW][COL], int row, int col);

//人人模式

int Ifwin(char board[ROW][COL], int row, int col, int x, int y);

//判断输赢

int check_x(char board[ROW][COL], int row, int col, int x, int y);

//判断竖直五子

int check_y(char board[ROW][COL], int row, int col, int x, int y);

//判断水平五子

int check_xy_up(char board[ROW][COL], int row, int col, int x, int y);

//判断斜上五子

int check_xy_down(char board[ROW][COL], int row, int col, int x, int y);

//判断斜下五子

三、menu菜单函数

void menu()

{ //完成菜单的初始化

printf("***********************\n");

printf("***********************\n");

printf("*****1.play 0.exit****\n");

printf("***********************\n");

printf("***********************\n");

printf("请输入:");

}

很简单,就不多说了

四、初始化棋盘Initboard函数

初始化棋盘,为数组一一存入空格

void Initboard(char board[ROW][COL], int row, int col)

{

int i = 0;

int j = 0;

for (i = 0; i < row; i++)

{

for (j = 0; j < col; j++)

{

board[i][j] = ' ';

}

}

}

五、显示棋盘Displayboard函数

打印简单的方格线,并打印数据内容

void Displayboard(char board[ROW][COL], int row, int col)

{

int i = 0;

int j = 0;

for (j = 0; j < col; j++)//打印横向y坐标

{

if (j == 0)//考虑到x轴所占的一格

{

printf(" %d ", j + 1);

}

else

{

printf(" %d ", j + 1);

}

}

printf("\n");

for (i = 0; i < row; i++)//打印数据

{

for (j = 0; j < col; j++)

{

if (j == 0)//顺带打印竖向x坐标

{

printf("%2d",i+1);//%md表示域宽为m

printf(" %c ",board[i][j]);

}

else

{

printf(" %c ", board[i][j]);

}

if (j < col - 1)

printf("|");

}

printf("\n");

//打印分割行

if (i < row - 1)

{

for (j = 0; j < col; j++)

{

if (j == 0)//同样考虑到y轴

printf(" ---");

else

printf("---");

if (j < col - 1)

printf("|");

}

printf("\n");

}

}

}

六、落子函数

玩家一落子——playermove_1

void Playermove_1(char board[ROW][COL], int row, int col, int *px, int*py)//ROW可以省,COL不行

{

int x = *px;

int y = *py;

while (1)

{

if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性

{

if (board[x -1][y- 1] == ' ')//保证落子点为空

{

board[x-1 ][y -1] = '*';

*px = x; *py = y;//如果开始xy输入不合法,则要对外部xy修改,所以选择传址操作

break;

}

else

{

printf("你不能在此处落子\n");

printf("玩家1落子,请重新输入x y坐标: ");

scanf("%d%d", &x, &y);

}

}

else

{

printf("输入坐标不合法\n");

printf("玩家落子,请重新输入x y坐标: ");

scanf("%d%d", &x, &y);

}

}

}

玩家2落子完全相同,就不赘叙了

电脑落子

void computermove(char board[ROW][COL], int row, int col)

{

int x = 0;

int y = 0;

//rand函数的使用需要srand函数的初始化,但srand不可以被重复调用,所以放在外部

while (1)

{

x = rand() % ROW;

y = rand() % COL;

if (board[x][y] == ' ')//x的范围在0~row-1,所以这里x不用-1了

{

board[x][y] = '#';

break;

}

}

}

七、判断输赢ifwin

根据我们下五子棋的经验,能获胜的地方必定是最后落子的水平线、竖直线、和两个斜对角线,我们只需对其进行检索即可。ifwin的返回值决定之后的switch语句

弱弱的说一句,虽然看起来多,但很多都是重复的。

int Ifwin(char board[ROW][COL], int row, int col, int x, int y)

{

int ret;

{

ret = check_x(board, row, col, x, y);

if (ret >= 5)

return 0;

ret = check_y(board, row, col, x, y);

if (ret >= 5)

return 0;

ret = check_xy_up(board, row, col, x, y);

if (ret >= 5)

return 0;

ret = check_xy_down(board, row, col, x, y);

if (ret >= 5)

return 0;

}

return 3;

}

int check_x(char board[ROW][COL], int row, int col, int x, int y)//检查x轴竖直方向

{

int sum = 1;

int old_x = x;

while (x < row && board[x - 1][y - 1] == board[x][y - 1])

{

sum++;

x++;

}

x = old_x;

while (x-2>= 0 && board[x - 1][y - 1] == board[x - 2][y - 1] )

{

sum++;

x--;

}

return sum;

}

int check_y(char board[ROW][COL], int row, int col, int x, int y)//检查y轴水平方向

{

int sum = 1;

int old_y = y;

while (y<col && board[x-1][y-1] == board[x-1][y] )

{

sum++;

y++;

}

y = old_y;

while (y-2 >= 0 && board[x-1][y-1] == board[x-1][y -2] )

{

sum++;

y--;

}

return sum;

}

int check_xy_up(char board[ROW][COL], int row, int col, int x, int y)//检查斜上45度

{

int sum = 1;

int old_x = x;

int old_y = y;

while (x<row && y - 2 >= 0 && board[x - 1][y - 1] == board[x][y - 2])

{

sum++;

x++;

y--;

}

x = old_x;

y = old_y;

while (x - 2 >= 0 && y <col && board[x - 1][y - 1] == board[x - 2][y])

{

sum++;

x--;

y++;

}

return sum;

}

int check_xy_down(char board[ROW][COL], int row, int col, int x, int y)//检查斜下45度

{

int sum = 1;

int old_x = x;

int old_y = y;

while (x<row && y <col && board[x - 1][y - 1] == board[x][y])

{

sum++;

x++;

y++;

}

x = old_x;

y = old_y;

while (board[x-1][y-1] == board[x -2][y-2 ] && x-2>=0 && y-2 >=0)

{

sum++;

x--;

y--;

}

return sum;

}

八、人机、人人模式的选择

初始选择界面

void game()

{

int input;

char board[ROW][COL] = { 0 };

Initboard(board, ROW, COL);

//初始化棋盘

Displayboard(board, ROW, COL);

//展示棋盘

printf("请选择模式:1.人机;2.玩家对战\n");

printf("请选择:");

do{

scanf("%d", &input);

printf("\n");

switch (input)

{

case 1:printf("游戏模式1开始!(注意:竖为x轴,横为y轴)\n"); game1(board, ROW, COL); break;

case 2:printf("游戏模式2开始!(注意:竖为x轴,横为y轴)\n"); ; game2(board, ROW, COL); break;

default:printf("请重新输入\n"); break;

}

} while (input != 1 && input != 2);//do while语句在输入错误时反复输入

}

game1的具体实现

void game1(char board[ROW][COL], int row, int col)

{

srand((unsigned int)time(NULL));//srand只要设置一次就可以,所以要放在while循环外

while (1)

{

int ret;

int count = 0;

int flag = 0;

//判读玩家的下棋

int x; int y;

printf("玩家落子,请依次输入x y坐标: ");

scanf("%d%d", &x, &y);

Playermove_1(board, row, col,&x, &y);

count++;

Displayboard(board, ROW, COL);

if (count == ROW*COL)//全下满则认为平局

ret = 1;

else

ret = Ifwin(board, ROW, COL, x, y);

switch (ret)

{

case 0:printf("玩家获胜\n"); flag = 1; break;

case 1:printf("平局\n"); flag = 1; break;

default: break;

}

if (flag == 1)//用flag跳出while循环

break;

//判断计算机的下棋

computermove(board, row, col);

count++;

Displayboard(board, ROW, COL);

if (count == ROW*COL)

ret = 1;

else

ret = Ifwin(board, ROW, COL, x, y);

switch (ret)

{

case 0:printf("电脑获胜\n"); flag = 1; break;

case 1:printf("平局\n"); flag = 1; break;

default: break;

}

if (flag == 1)

break;

}

}

作者觉得写的是挺啰嗦,欢迎留言建议。game2和game1玩家一的内容很相近,就不赘述

九、作者遇到的坑点

1.输入的坐标和存在数组里的下标有减一的关系,在写的时候不要写忘记了

2.传址操作才能改变函数外的变量值

十、完整的代码

头文件就省了

int main()

{

int input;

do{

system("cls");//清屏

menu();

scanf("%d", &input);

switch (input)

{

case 1:

printf("游戏开始\n\n"); game(); break;

case 0:

printf("退出游戏\n"); break;

default:

printf("请重新输入\n"); break;

}

Sleep(3000);//暂停3秒

} while (input);//do while语句实现可以反复玩

return 0;

}

void menu()

{ //完成菜单的初始化

printf("***********************\n");

printf("***********************\n");

printf("*****1.play 0.exit****\n");

printf("***********************\n");

printf("***********************\n");

printf("请输入:");

}

void Initboard(char board[ROW][COL], int row, int col)

{

int i = 0;

int j = 0;

for (i = 0; i < row; i++)

{

for (j = 0; j < col; j++)

{

board[i][j] = ' ';

}

}

}

void Displayboard(char board[ROW][COL], int row, int col)

{

int i = 0;

int j = 0;

for (j = 0; j < col; j++)//打印横向y坐标

{

if (j == 0)//考虑到x轴所占的一格

{

printf(" %d ", j + 1);

}

else

{

printf(" %d ", j + 1);

}

}

printf("\n");

for (i = 0; i < row; i++)//打印数据

{

for (j = 0; j < col; j++)

{

if (j == 0)//顺带打印竖向x坐标

{

printf("%2d",i+1);//%md表示域宽为m

printf(" %c ",board[i][j]);

}

else

{

printf(" %c ", board[i][j]);

}

//数字表示坐标

if (j < col - 1)

printf("|");

}

printf("\n");

//打印分割行

if (i < row - 1)

{

for (j = 0; j < col; j++)

{

if (j == 0)//同样考虑到y轴

printf(" ---");

else

printf("---");

if (j < col - 1)

printf("|");

}

printf("\n");//别忘记这里也要换行

}

}

}

void game()

{

int input;

char board[ROW][COL] = { 0 };

Initboard(board, ROW, COL);

//初始化棋盘

Displayboard(board, ROW, COL);

//展示棋盘

printf("请选择模式:1.人机;2.玩家对战\n");

printf("请选择:");

do{

scanf("%d", &input);

printf("\n");

switch (input)

{

case 1:printf("游戏模式1开始!(注意:竖为x轴,横为y轴)\n"); game1(board, ROW, COL); break;

case 2:printf("游戏模式2开始!(注意:竖为x轴,横为y轴)\n"); ; game2(board, ROW, COL); break;

default:printf("请重新输入\n"); break;

}

} while (input != 1 && input != 2);//do while语句在输入错误时反复输入

}

void game1(char board[ROW][COL], int row, int col)

{

srand((unsigned int)time(NULL));//srand只要设置一次就可以,所以要放在while循环外

while (1)

{

int ret;

int count = 0;

int flag = 0;

//判读玩家的下棋

int x; int y;

printf("玩家落子,请依次输入x y坐标: ");

scanf("%d%d", &x, &y);

Playermove_1(board, row, col,&x, &y);

count++;

Displayboard(board, ROW, COL);

if (count == ROW*COL)//全下满则认为平局

ret = 1;

else

ret = Ifwin(board, ROW, COL, x, y);

switch (ret)

{

case 0:printf("玩家获胜\n"); flag = 1; break;

case 1:printf("平局\n"); flag = 1; break;

default: break;

}

if (flag == 1)//用flag跳出while循环

break;

//判断计算机的下棋

computermove(board, row, col);

count++;

Displayboard(board, ROW, COL);

if (count == ROW*COL)

ret = 1;

else

ret = Ifwin(board, ROW, COL, x, y);

switch (ret)

{

case 0:printf("电脑获胜\n"); flag = 1; break;

case 1:printf("平局\n"); flag = 1; break;

default: break;

}

if (flag == 1)

break;

}

}

void game2(char board[ROW][COL], int row, int col)

{

while (1)

{

int ret;

int count = 0;

int flag = 0;

int x; int y;

//判读玩家1的下棋

printf("玩家1落子,请输入坐标:(注意:竖为x轴,横为y轴)");

scanf("%d%d", &x, &y);

Playermove_1(board, row, col, &x, &y);

count++;

Displayboard(board, ROW, COL);

if (count == ROW*COL)

ret = 1;

else

ret = Ifwin(board, ROW, COL, x, y);

switch (ret)

{

case 0:printf("玩家1获胜\n"); flag = 1; break;

case 1:printf("平局\n"); flag = 1; break;

default: break;

}

if (flag == 1)

break;

//判断玩家2的下棋

printf("玩家2落子,请输入坐标:(注意:竖为x轴,横为y轴)");

scanf("%d%d", &x, &y);

Playermove_2(board, row, col, &x, &y);

count++;

Displayboard(board, ROW, COL);

if (count == ROW*COL)

ret = 1;

else

ret = Ifwin(board, ROW, COL, x, y);

switch (ret)

{

case 0:printf("玩家2获胜\n"); flag = 1; break;

case 1:printf("平局\n"); flag = 1; break;

default: break;

}

if (flag == 1)

break;

}

}

void Playermove_1(char board[ROW][COL], int row, int col, int *px, int*py)//ROW可以省,COL不行

{

int x = *px;

int y = *py;

while (1)

{

if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性

{

if (board[x -1][y- 1] == ' ')//保证落子点为空

{

board[x-1 ][y -1] = '*';

*px = x; *py = y;//如果开始xy输入不合法,要对外部xy修改,所以要传址操作

break;

}

else

{

printf("你不能在此处落子\n");

printf("玩家1落子,请重新输入x y坐标: ");

scanf("%d%d", &x, &y);

}

}

else

{

printf("输入坐标不合法\n");

printf("玩家落子,请重新输入x y坐标: ");

scanf("%d%d", &x, &y);

}

}

}

void Playermove_2(char board[ROW][COL], int row, int col, int *px, int*py)

{

int x = *px;

int y = *py;

while (1)

{

if (x >= 1 && x <= row && y >= 1 && y <= col)//判断输入坐标的合法性

{

if (board[x - 1][y - 1] == ' ')//保证落子点为空

{

board[x - 1][y - 1] = '#';

*px = x; *py = y;

break;

}

else

{

printf("你不能在此处落子\n");

printf("玩家2落子,请重新输入x y坐标: ");

scanf("%d%d", &x, &y);

}

}

else

{

printf("输入坐标不合法\n");

printf("玩家落子,请重新输入x y坐标: ");

scanf("%d%d", &x, &y);

}

}

}

void computermove(char board[ROW][COL], int row, int col)

{

int x = 0;

int y = 0;

while (1)

{

x = rand() % ROW;

y = rand() % COL;

if (board[x][y] == ' ')

{

board[x][y] = '#';

break;

}

}

}

int Ifwin(char board[ROW][COL], int row, int col, int x, int y)

{

int ret;

{

ret = check_x(board, row, col, x, y);

if (ret >= 5)

return 0;

ret = check_y(board, row, col, x, y);

if (ret >= 5)

return 0;

ret = check_xy_up(board, row, col, x, y);

if (ret >= 5)

return 0;

ret = check_xy_down(board, row, col, x, y);

if (ret >= 5)

return 0;

}

return 3;

}

int check_x(char board[ROW][COL], int row, int col, int x, int y)//检查x轴竖直方向

{

int sum = 1;

int old_x = x;

while (x < row && board[x - 1][y - 1] == board[x][y - 1])

{

sum++;

x++;

}

x = old_x;

while (x-2>= 0 && board[x - 1][y - 1] == board[x - 2][y - 1] )

{

sum++;

x--;

}

return sum;

}

int check_y(char board[ROW][COL], int row, int col, int x, int y)//检查y轴水平方向

{

int sum = 1;

int old_y = y;

while (y<col && board[x-1][y-1] == board[x-1][y] )

{

sum++;

y++;

}

y = old_y;

while (y-2 >= 0 && board[x-1][y-1] == board[x-1][y -2] )

{

sum++;

y--;

}

return sum;

}

int check_xy_up(char board[ROW][COL], int row, int col, int x, int y)//检查斜上45度

{

int sum = 1;

int old_x = x;

int old_y = y;

while (x<row && y - 2 >= 0 && board[x - 1][y - 1] == board[x][y - 2])

{

sum++;

x++;

y--;

}

x = old_x;

y = old_y;

while (x - 2 >= 0 && y <col && board[x - 1][y - 1] == board[x - 2][y])

{

sum++;

x--;

y++;

}

return sum;

}

int check_xy_down(char board[ROW][COL], int row, int col, int x, int y)//检查斜下45度

{

int sum = 1;

int old_x = x;

int old_y = y;

while (x<row && y <col && board[x - 1][y - 1] == board[x][y])

{

sum++;

x++;

y++;

}

x = old_x;

y = old_y;

while (board[x-1][y-1] == board[x -2][y-2 ] && x-2>=0 && y-2 >=0)

{

sum++;

x--;

y--;

}

return sum;

}

如果对你有帮助和启发,作者感到很高兴。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 利用C语言实现五子棋游戏 的全部内容, 来源链接: utcz.com/p/246986.html

回到顶部