五一祝福
因为这篇博文实在五一这天完成的,所以呢,在介绍五子棋之前,先祝各位支持小白的大佬都五一快乐!
花了点时间下了个“五一快乐”的五子棋,哈哈哈哈哈哈,还不太熟练,所以写的有点丑,勉强过的去就行,不知道佬们看不看得出来,还是说实在一点都不像,不过没关系,佬们阅读了之后希望可以给我修正一下,去玩玩。那个’乐‘字确实没整好,哈哈哈,看起来超别扭
如下图所示:
祝福送给打架了之后就让我们来说一说正文吧。
五子棋的实现
五子棋的实现分为一下几个功能的实现:
- 首先是先构建棋盘,我们这里用了一个二维数组chessboard来对我们的棋盘进行初始化和放置棋子
- 实现展示棋盘的函数void ShowChessBoard(int board[ROW][COL])
- 玩家1下棋,我们用函数void PlayerMove(int board[ROW][COL], int who)来实现,后面那个参数who 传的是谁就是到谁下棋
- 玩家1下棋之后棋盘会有变化,我们要对棋局进行判断是否达成了五子连珠,或者说整个棋盘的棋子都放满了还没结束,那就是平局,否则就是继续进行棋局,我们用函数int IsOver(int board[ROW][COL])来进行判断,其中这个函数的判断方法是通过调用函数int ChessCount(int board[ROW][COL], enum Dir d)来判断每下一步棋之后该位置的八个方向都进行判断,看是否达成其中至少有一个方向满足五子连珠来判断当前棋局的情况
- 玩家2下棋,将第3 ,4中的玩家1变成玩家2重复上述第3 , 4步。
1 菜单
代码实现:
void menu()
{
printf("****************************\n");
printf("******1. 开始 0.退出******\n");
printf("****************************\n");
printf("请选择 :> ");
}
2.展示棋盘
代码实现:
void ShowChessBoard(int board[ROW][COL])
{
printf("\033c");
printf("玩家1——●\n");
printf("玩家2——○\n");
printf("\n\n ");
//打印y坐标轴
for (int i = 0; i < COL; i++) {
printf("%3d", i);
}
printf("\n");
for (int i = 0; i < ROW; i++) {
printf("%3d", i);//打印x坐标轴
for (int j = 0; j < COL; j++) {
if (board[i][j] == Player1) {
//player1
printf(" ●");//用黑棋表示玩家1的棋子
}
else if (board[i][j] == Player2) {
//player2
printf(" ○");//用白棋表示玩家2的棋子
}
else {
//Space
printf(" + ");//空余部分默认为'+'
}
}
printf("\n");
}
}
3.玩家下棋
代码实现:
void PlayerMove(int board[ROW][COL], int who)
{
while (1) {
printf("\n玩家[%d] 请输入你需要下棋的位置:> ", who);
scanf("%d %d", &x, &y);//输入一个下棋的坐标
if (x<0 || y > COL) {
printf("非法坐标,重新输入!\n");
}
else if (board[x][y] != 0) {
printf("该位置已被占用!\n");
}
else {
board[x][y] = who;//把下棋的玩家对应的常量值赋值给该位置对应的值
break;
}
}
}
4.统计下棋位置所对应的同种棋子的个数
代码实现:
int ChessCount(int board[ROW][COL], enum Dir d)
{
int _x = x;
int _y = y;
int count = 0;
while (1) {
switch (d) {
case LEFT:
_y--;
break;
case RIGHT:
_y++;
break;
case UP:
_x--;
break;
case DOWN:
_x++;
break;
case LEFT_UP:
_x--, _y--;
break;
case RIGHT_DOWN:
_x++, _y++;
break;
case RIGHT_UP:
_x--, _y++;
break;
case LEFT_DOWN:
_x++, _y--;
break;
}
if (_x < 0 || _x > ROW - 1 || _y < 0 || _y > COL - 1) {
break;
}//对下的棋子位置进行八个方向位置的连续的同种棋子个数进行统计
if (board[x][y] == board[_x][_y]) {
count++;
}
else {
break;
}
}
return count;
}
5.判断棋局是否结束
代码实现:
int IsOver(int board[ROW][COL])
{
//将八个方向对应的同种棋子转变为统计四条直线上对应的同种棋子总数
int count1 = ChessCount(board, LEFT) + ChessCount(board, RIGHT) + 1;
int count2 = ChessCount(board, UP) + ChessCount(board, DOWN) + 1;
int count3 = ChessCount(board, LEFT_UP) + ChessCount(board, RIGHT_DOWN) + 1;
int count4 = ChessCount(board, LEFT_DOWN) + ChessCount(board, RIGHT_UP) + 1;
//只要有一个方向连续的同种棋子数满足大于等于5个,那么相对应的玩家获得胜利
if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5) {
if (board[x][y] == Player1) {
return PLAYER1_WIN;
}
else {
return PLAYER2_WIN;
}
}
//否则如果棋盘还没下满,也就是只要还有位置没放棋子,则对局继续
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (board[i][j] == 0) {
return CONTINUE;
}
}
}
//以上情况都不符合那就是平局
return DROW;
}
6.将以上函数功能进行结合的game 函数
代码实现:
void game()
{
//初始化
int chessboard[ROW][COL];
memset(chessboard, '\0', sizeof(chessboard));
//判断结果的变量,默认初始化为对局继续
int result = CONTINUE;
do {
ShowChessBoard(chessboard);
PlayerMove(chessboard, Player1);
result = IsOver(chessboard);
if (CONTINUE != result) {
break;
}
ShowChessBoard(chessboard);
PlayerMove(chessboard, Player2);
result = IsOver(chessboard);
if (CONTINUE != result) {
break;
}
} while (1);
ShowChessBoard(chessboard);
switch (result) {
case PLAYER1_WIN:
printf("恭喜玩家1获胜!\n");
break;
case PLAYER2_WIN:
printf("恭喜玩家2获胜了!\n");
break;
case DROW:
printf("平局,不服可以再战!\n");
break;
}
}
完整代码:
game.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ROW 30
#define COL 30
#define Player1 1
#define Player2 2
#define CONTINUE 0
#define PLAYER1_WIN 1
#define PLAYER2_WIN 2
#define DROW 3
enum dir
{
LEFT,
RIGHT,
UP,
DOWN,
LEFT_UP,
RIGHT_UP,
LEFT_DOWN,
RIGHT_DOWN
};
void menu();
void game();
void ShowChessBoard(int chessboard[ROW][COL]);
int IsOver(int chessboard[ROW][COL]);
void PlayerMove(int chessboard[ROW][COL], int who);
int ChessCount(int chessboard[ROW][COL], enum dir d);
game.c
#include "game.h"
int x = 0;
int y = 0;
void menu()
{
printf("****************************\n");
printf("******1. 开始 0.退出******\n");
printf("****************************\n");
printf("请选择 :> ");
}
void ShowChessBoard(int board[ROW][COL])
{
printf("\033c");
printf("玩家1——●\n");
printf("玩家2——○\n");
printf("\n\n ");
//打印y坐标轴
for (int i = 0; i < COL; i++) {
printf("%3d", i);
}
printf("\n");
for (int i = 0; i < ROW; i++) {
printf("%3d", i);//打印x坐标轴
for (int j = 0; j < COL; j++) {
if (board[i][j] == Player1) {
//player1
printf(" ●");//用黑棋表示玩家1的棋子
}
else if (board[i][j] == Player2) {
//player2
printf(" ○");//用白棋表示玩家2的棋子
}
else {
//Space
printf(" + ");//空余部分默认为'+'
}
}
printf("\n");
}
}
void PlayerMove(int board[ROW][COL], int who)
{
while (1) {
printf("\n玩家[%d] 请输入你需要下棋的位置:> ", who);
scanf("%d %d", &x, &y);//输入一个下棋的坐标
if (x<0 || y > COL) {
printf("非法坐标,重新输入!\n");
}
else if (board[x][y] != 0) {
printf("该位置已被占用!\n");
}
else {
board[x][y] = who;//把下棋的玩家对应的常量值赋值给该位置对应的值
break;
}
}
}
int ChessCount(int board[ROW][COL], enum Dir d)
{
int _x = x;
int _y = y;
int count = 0;
while (1) {
switch (d) {
case LEFT:
_y--;
break;
case RIGHT:
_y++;
break;
case UP:
_x--;
break;
case DOWN:
_x++;
break;
case LEFT_UP:
_x--, _y--;
break;
case RIGHT_DOWN:
_x++, _y++;
break;
case RIGHT_UP:
_x--, _y++;
break;
case LEFT_DOWN:
_x++, _y--;
break;
}
if (_x < 0 || _x > ROW - 1 || _y < 0 || _y > COL - 1) {
break;
}//对下的棋子位置进行八个方向位置的连续的同种棋子个数进行统计
if (board[x][y] == board[_x][_y]) {
count++;
}
else {
break;
}
}
return count;
}
int IsOver(int board[ROW][COL])
{
//将八个方向对应的同种棋子转变为统计四条直线上对应的同种棋子总数
int count1 = ChessCount(board, LEFT) + ChessCount(board, RIGHT) + 1;
int count2 = ChessCount(board, UP) + ChessCount(board, DOWN) + 1;
int count3 = ChessCount(board, LEFT_UP) + ChessCount(board, RIGHT_DOWN) + 1;
int count4 = ChessCount(board, LEFT_DOWN) + ChessCount(board, RIGHT_UP) + 1;
//只要有一个方向连续的同种棋子数满足大于等于5个,那么相对应的玩家获得胜利
if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >= 5) {
if (board[x][y] == Player1) {
return PLAYER1_WIN;
}
else {
return PLAYER2_WIN;
}
}
//否则如果棋盘还没下满,也就是只要还有位置没放棋子,则对局继续
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (board[i][j] == 0) {
return CONTINUE;
}
}
}
//以上情况都不符合那就是平局
return DROW;
}
void game()
{
//初始化
int chessboard[ROW][COL];
memset(chessboard, '\0', sizeof(chessboard));
//判断结果的变量,默认初始化为对局继续
int result = CONTINUE;
do {
ShowChessBoard(chessboard);
PlayerMove(chessboard, Player1);
result = IsOver(chessboard);
if (CONTINUE != result) {
break;
}
ShowChessBoard(chessboard);
PlayerMove(chessboard, Player2);
result = IsOver(chessboard);
if (CONTINUE != result) {
break;
}
} while (1);
ShowChessBoard(chessboard);
switch (result) {
case PLAYER1_WIN:
printf("恭喜玩家1获胜!\n");
break;
case PLAYER2_WIN:
printf("恭喜玩家2获胜了!\n");
break;
case DROW:
printf("平局,不服可以再战!\n");
break;
}
}
test.c
#include "game.h"
int main()
{
int input = 0;
do
{
menu();
scanf("%d", &input);
switch (input)
{
case 1:
printf("欢迎来到五子棋---玩家1vs玩家2\n");
printf("祝您游戏愉快\n");
game();
break;
case 0:
printf("游戏已退出\n");
break;
default:
printf("选择错误,请重新输入!\n");
break;
}
} while (input);
return 0;
}
好了,我们的五子棋实现就到这了,五一快乐哦~