当前位置:首页 » 《随便一记》 » 正文

C语言实现五子棋小游戏_安河桥畔的博客

23 人参与  2021年11月19日 12:23  分类 : 《随便一记》  评论

点击全文阅读


C语言实现五子棋

基本思路

1.五子棋需要棋盘并能够记录玩家落子情况,可以使用二维数来保存数据。
2.采用双人对战模式。
3.五子棋实现的主要难度是判断是否构成五子连珠,采用以下方法:
在这里插入图片描述
在某一点落子时,判断以该坐标为中心的八个方向,有无与所落子颜色相同的棋子,如果有则统计相同棋子数目,将相对方向的数目相加构成一组,如果哪一组有五或以上相同的棋子,这个方向就构成了五子连珠。

代码实现

多文件形式,整个程序包括一个头文件game.h,两个源文件game.c和main.c
1.game.h——宏定义和头文件包含以及函数声明等

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<windows.h>
void Game();//函数声明
#define ROW 21//棋盘大小
#define COL 21

#define PLAYER1 1
#define PLAYER2 2
#define NEXT 3
#define DRAW 4

//八个不同的方向
#define UP 10
#define RITHT_UP 11
#define RIGHT 12
#define RIGHT_DOWN 13
#define DOWN 14
#define LEFT_DOWN 15
#define LEFT 16
#define LEFT_UP 17

2.main.c——程序入口,游戏主菜单,对Game函数调用

#include"game.h"

void Menu()
{
	printf("+----------------------------------+\n");
	printf("+      1.Play       2.Exit         +\n");
	printf("+----------------------------------+\n");
}
int main()
{
	int select = 0;
	int quit = 0;

	//游戏为死循环模式,不选择退出则一直进行
	while (!quit){
		Menu();
		printf("Please select:\n");
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			Game();
			break;
		case 2:
			quit = 1;
			break;
		default:
			printf("Enter error!\n");
			break;
		}
	}
	printf("Bye-bye!\n");
	system("pause");
	return 0;
}

3.game.c——Game函数实现

#include"game.h"

//定义两个全局变量存放落子坐标,这样做的好处是不用将\
  坐标作为参数传入各个函数
int x = 0;
int y = 0;
static void ShowBoard(int ar[][COL], int row,int col)
{
	system("cls");
	printf("   ");
	for (int i = 0; i < col; i++)
	{
		printf("%2d ",i);
	}
	printf("\n");
	for (int i = 0; i < row; i++)
	{
		printf("%-2d", i);
		for (int j = 0; j < col; j++)
		{
			//遍历数组,打印棋盘对应内容
			if (ar[i][j] == 0){
				printf("  .");
			}
			else if (ar[i][j] == PLAYER1){
				printf("  O");
			}
			else if (ar[i][j] == PLAYER2){
				printf("  X");
			}
			else{
				printf("Bug");
			}
		}
		printf("\n");
	}
}

static void PlayerMove(int ar[][COL], int row, int col,int who)
{
	
	while (1){
		printf("Please enter your position Player %d<x,y>\n",who);
		scanf("%d %d", &x, &y);
		//判断坐标合法性
		if (x<0 || x>row - 1 || y<0 || y>row - 1){
			printf("Ener error!\n");
			continue;
		}
		if (ar[x][y] == 0){
			ar[x][y] = who;
			break;//输入正确的坐标才能跳出循环
		}
		else{
			printf("This position is not empty.\n");
			continue;
		}
	}
}

static int ChessCount(int ar[][COL],int direction)
{
	int count = 0;

	//避免影响落子坐标x和y的值,定义两个新的变量存放
	int x_ = x;
	int y_ = y;
//#define UP 10
//#define RITHT_UP 11
//#define RIGHT 12
//#define RIGHT_DOWN 13
//#define DOWN 14
//#define LEFT_DOWN 15
//#define LEFT 16
//#define LEFT_UP 17

	//状态机(while死循环+switch case)
	while (1){
		switch (direction){
		case UP:
			x_--;
			break;
		case RITHT_UP:
			x_--, y_++;
			break;
		case RIGHT:
			y_++;
			break;
		case RIGHT_DOWN:
			x_++, y_++;
			break;
		case DOWN:
			x_++;
			break;
		case LEFT_DOWN:
			x_++, y_--;
			break;
		case LEFT:
			y_--;
			break;
		case LEFT_UP:
			x_--, y_--;
			break;
		default:
			//BUG
			break;
		}
		//先判断坐标合法性
		if (x_<0 || x_>ROW - 1 || y_<0 || y_>COL - 1){
			break;
		}

		//周边棋子相同时,count+1,再循环\
		  直到棋子不相同或者到边界位置
		if (ar[x_][y_] == ar[x][y]){
			count++;
		}
		else{
			break;
		}
	}
return count;
}

static int Judge(int ar[][COL],int row,int col)
{
	
	int count = 0;//相同棋子的个数

	//纵向相同棋子个数
	count = ChessCount(ar, UP) + ChessCount(ar, DOWN)+1;
	if (count >= 5){
		return ar[x][y];
	}

	//横向相同棋子个数
	count = ChessCount(ar, LEFT) + ChessCount(ar, RIGHT)+1;
	if (count >= 5){
		return ar[x][y];
	}

	//左上到右下方向
	count = ChessCount(ar, LEFT_UP) + ChessCount(ar, RIGHT_DOWN)+1;
	if (count >= 5){
		return ar[x][y];
	}

	//左下到右上方向
	count = ChessCount(ar, RITHT_UP) + ChessCount(ar, LEFT_DOWN)+1;
	if (count >= 5){
		return ar[x][y];
	}

	//程序执行到这里,则说明没有五子连珠,只有平局或者继续两种情况
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (ar[i][j] != 0){
				return NEXT;
			}
		}
	}
	return DRAW;
}

void Game()
{
	int board[ROW][COL] = { 0 };//定义二维数组存放落子信息

	int ret = 0;//存放Judge函数返回之前
	while (1){
		ShowBoard(board, ROW, COL);//展示棋盘
		PlayerMove(board, ROW, COL,PLAYER1);//玩家落子
		ret = Judge(board,ROW,COL);//判断结果
		if (ret != NEXT){
			//判断结果不不为NEXT则跳出循环
			break;
		}
		ShowBoard(board, ROW, COL);
		PlayerMove(board, ROW, COL,PLAYER2);
		ret = Judge(board,ROW,COL);
		if (ret != NEXT){
			break;
		}
	}

	//游戏结果
	switch (ret){
	case PLAYER1:
		printf("Player1 win!\n");
		break;
	case PLAYER2:
		printf("Player2 win!\n");
		break;
	case DRAW:
		printf("Draw!\n");
		break;
	default:
		printf("Bug!\n");
		break;
	}
}

点击全文阅读


本文链接:http://zhangshiyu.com/post/31033.html

落子  棋子  坐标  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1