手把手教你C语言五子棋的实现(双玩家对战)
Posted 小赵小赵福星高照~
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教你C语言五子棋的实现(双玩家对战)相关的知识,希望对你有一定的参考价值。
五子棋的实现
我们依然分以下三个文件来实现五子棋:
test.c - 主函数 - 设计整个游戏过程
游戏的逻辑
game.c - 函数的实现
game.h - 函数的声明
五子棋和三子棋十分像,仅仅是输赢的检查不一样,我们这次设计成两个玩家对着下的游戏模式
成品展示
首先我们打印一个菜单,让玩家选择,选择后会出现棋盘界面,然后让玩家1输入坐标下棋。
然后玩家2再输入坐标,之后实现玩家1走和玩家2走,直到一方横竖左斜右斜连成五子则获得胜利,游戏结束。
首先讲一讲我们整体的思路框架,我们设计这个游戏,让玩家想玩的时候可以一直玩,所以我们采用do…while循环语句,然后打印菜单,写一个菜单函数,让玩家进行选择,这里我们采用switch分支语句,当我们选择1时进入游戏,此时需要写一个游戏函数,选择0时退出游戏,选择其他时,告诉他选择错误,重新输入,我们发现当选择1和选择错误时我们需要循环继续,退出游戏是我们退出循环的时候,所以我们将while()里的循环条件设置成玩家输入的选择。
我们的整体逻辑框架如下代码:
test.c
void game()
{
//游戏的实现,这里先不写
}
void menu()
{
printf("********************\\n");
printf("*******1.play*******\\n");
printf("*******0.exit*******\\n");
printf("********************\\n");
}
int main()
{
int input=0;
do
{
menu();
printf("请选择:>");
scanf("%d",&input);
switch(input)
{
case 1:
game();
break;
case 2:
printf("退出游戏\\n");
break;
default:
printf("选择错误,重新选择\\n");
break;
}
}while(input)
return 0;
}
那么游戏的实现,我们该怎么弄呢?
从刚开始我们进行成品展示时,实现这个游戏,我们需要:
1、创建一个存储数据的字符数组
行列的元素个数我们用#define在game.h中定义常量,这样我们需要修改棋盘行列时就很简单,使我们的游戏程序更加灵活多变。
char board[ROW][COL] = { 0 };
2、初始化数据
首先打印的界面数据为空的,我们需要初始化数据为空格
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] = ' ';
}
}
}
3、打印棋盘
打印棋盘代码:
这里我们打印棋盘的代码与上篇三子棋文章一样,这就看到前面用#define定义行和列的好处了,当我们想打印10*10的棋盘时,直接将ROW,COL改为10就好了。
void DisplayBoard(char board[ROW][COL],int row,int col)
{
int i=0;
for(i=0;i<row;i++)
{
int j=0;
for(j=0;j<col;j++)
{
printf(" %c ",board[i][j]);
if(j<col-1)
printf("|");
}
printf("\\n");
if(i<row-1)
{
for(j=0;j<col;j++)
{
printf("---");
if(j<col-1)
printf("|");
}
printf("\\n");
}
}
}
这里以3*3棋盘讲解为例:
我们把打印棋盘分成了打印数据行和打印分割行,我们发现分割行我们只打印两次,最后一行我们不需要分割行,所以我们将判断条件设置为i<row-1时我们才打印分割行,我们再看列,最后一行我们不打印|,所以|的打印我们给判断条件j<col-1。
4、玩家走棋
玩家走的函数代码如下:
void PlayerMove(int num, char board[ROW][COL], int row, int col, char set)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家%d走,请输入下棋的坐标:>", num);
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = set;
break;
}
else
{
printf("该坐标已被占用,请重新选择坐标\\n");
}
}
else
{
printf("坐标非法,请重新输入\\n");
}
}
}
玩家走的函数参数我们给定5个,分别是显示哪个玩家的参数、棋盘数组、行、列、每个玩家要下后的展示字符(好比黑白棋),首先我们需要判断该玩家输入的下棋坐标是否合法,我们的棋盘是十行十列,所以玩家输入的坐标需要在范围内,如果坐标合法了,我们再判断该坐标是否被占用,如果没有被占用,则将该坐标所对应数组下标数据赋值为传进来的参数set(因为我们玩家玩游戏时输入(1,1)坐标时,对应的数组下标为board[0] [0],所以我们判断条件的数组下标需要设置为x-1,y-1)。
5、判断输赢
首先我们看一下判断输赢的基本框架:
我们设定判断输赢函数的返回值
1.玩家1赢,返回*
2.玩家2赢,返回#
3.平局,返回Q
4.游戏继续,返回C
ret = IsWin(board, ROW, COL);
//用ret来接收判断输赢函数的返回值
//1.玩家1赢,返回*
//2.玩家2赢,返回#
//3.平局,返回Q
//4.游戏继续,返回C
我们在每个玩家走后判断输赢,在循环内部判断,如果返回的不是C,则说明游戏结束,则跳出循环判断其他三种情况
if (ret != 'C')//游戏已结束
{
break;
}
循环外面判断:
if (ret == '*')
{
printf("玩家1赢\\n");
}
else if (ret == '#')
{
printf("玩家2赢\\n");
}
else if (ret == 'Q')
{
printf("平局\\n");
}
判断输赢函数代码:
char IsWin(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++)
{
if (board[i][j] == ' ')
{
continue;
}
else if ((board[i][j] == board[i][j + 1] && board[i][j] == board[i][j + 2] && board[i][j] == board[i][j + 3] && board[i][j] == board[i][j + 4]) ||
//横
(board[i][j] == board[i + 1][j] && board[i][j] == board[i + 2][j] && board[i][j] == board[i + 3][j] && board[i][j] == board[i + 4][j]) ||
//竖
(board[i][j] == board[i + 1][j + 1] && board[i][j] == board[i + 2][j + 2] && board[i][j] == board[i + 3][j + 3] && board[i][j] == board[i + 4][j + 4]) ||
//右斜
(board[i][j] == board[i + 1][j - 1] && board[i][j] == board[i + 2][j - 2] && board[i][j] == board[i + 3][j - 3] && board[i][j] == board[i + 4][j - 4]))
//左斜
{
return board[i][j];
}
else
{
continue;
}
}
}
if (IsFull(board, row, col) == 1)
{
return 'Q';
}
return 'C';
}
我们需要判断行、列、左斜,右斜是否形成五个一样的字符,以及棋盘是否满,来判断游戏是否结束,因为我们设定1.玩家1赢,返回*,2.玩家2赢,返回#。所以我们判断行、列、左斜、右斜时可以直接return里面任意一个字符就可以知道是谁赢了,或者是平局,平局我们需要写一个判断棋盘是否满的函数,如果返回值为1,则表示满–平局,如果玩家1赢,玩家2赢,平局这三个都不满足,则游戏继续,return字符‘C’。
判断棋盘是否满的代码
//判断棋盘是否满
int IsFull(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++)
{
if (board[i][j] == ' ')
return 0;
}
}
return 1;
}
访问数组每个元素,如果有一个元素等于字符空格,则不满,返回0。
需要注意每个玩家走后都要进行判断输赢
test.c中的游戏函数代码如下:
void game()
{
//1.创建存储数据的字符数组,行列的元素我们用#define定义,这样我们需要修改棋盘行列时就很简单
char board[ROW][COL] = { 0 };
//2.首先打印的界面数据为空的,我们需要初始化数据为空格
InitBoard(board, ROW, COL);
//3.打印棋盘
DispalyBoard(board, ROW, COL);
char ret = 0;
while (1)
{
//4.玩家1走
PlayerMove(1, board, ROW, COL, '*');
//判断输赢
ret = IsWin(board, ROW, COL);
//1.玩家1赢,返回*
//2.玩家2赢,返回#
//3.平局,返回Q
//4.游戏继续,返回C
DispalyBoard(board, ROW, COL);
if (ret != 'C')//游戏已结束
{
break;
}
//玩家2走
PlayerMove(2, board, ROW, COL, '#');
//ComputerMove(board, ROW, COL);
ret = IsWin(board, ROW, COL);
DispalyBoard(board, ROW, COL);
if (ret != 'C')//游戏已结束
{
break;
}
}
if (ret == '*')
{
printf("玩家1赢\\n");
}
else if (ret == '#')
{
printf("玩家2赢\\n");
}
else if (ret == 'Q')
{
printf("平局\\n");
}
}
游戏的实现中用到的函数我们在game.h文件中声明
game.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 10
#define COL 10
//初始化数组数据函数声明
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘函数声明
void DispalyBoard(char board[ROW][COL], int row, int col);
//玩家走函数声明
void PlayerMove(int num, char board[ROW][COL], int row, int col, char set);
//检查输赢函数声明
char IsWin(char board[ROW][COL], int row, int col);
我们在game.c中写函数的定义
game.c
#include"game.h"
//初始化数组数据函数定义
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 DispalyBoard(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++)
{
printf(" %c ", board[i][j]);
if (j < col - 1)
{
printf("|");
}
}
printf("\\n");
if (i < row - 1)
{
for (j = 0; j < col; j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
printf("\\n");
}
}
}
//玩家走函数定义
void PlayerMove(int num, char board[ROW][COL], int row, int col, char set)
{
int x = 0;
int y = 0;
while (1)
{
printf("玩家%d走,请输入下棋的坐标:>", num);
scanf("%d %d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = set;
break;
}
else
{
printf("该坐标已被占用,请重新选择坐标\\n");
}
}
else
{
printf("坐标非法,请重新输入\\n");
}
}
}
//判断棋盘是否满
int IsFull(char board[ROW][以上是关于手把手教你C语言五子棋的实现(双玩家对战)的主要内容,如果未能解决你的问题,请参考以下文章