【项目展示】自己用C语言编写的五子棋小程序

博主在大一时用C语言编写了一个五子棋小程序,通过CUI界面进行双人对战。项目介绍了核心算法,即在四个方向检测五子连珠,并分享了项目规格、源代码和运行结果。未来计划包括改进现有项目和尝试GUI化。
摘要由CSDN通过智能技术生成

1、前言

2015年,我刚刚上大一。大一上学期,我们就学习了C语言这门课程。学了大概两个多月吧,我就心血来潮,在学校图书馆的机房里自主编写了我的第一个C语言项目——五子棋小程序。
我依稀记得,那个夏日的夜晚,风带着些许暑气,一个少年背着沉重的书包,拖着疲惫却又轻快的身躯,满意地走出图书馆的身影。他的心中有说不尽的甜——毕竟,做成了此生第一个完全由自己开发的小游戏。
而当时的我编写的五子棋小游戏是什么样子的呢?当时的我还不会GUI编程(虽然到现在也还没学会……),所以就借鉴了一下更早以前玩过的一个基于CUI的围棋小程序。那个围棋小程序,是用点“·”来表示棋盘上的每一个交叉点,用加号“+”来表示九个星位,用字母x来表示黑棋,用字母o来表示白棋。所以我的第一个五子棋小程序,也是这么做的。
用一个二维数组来储存当前棋盘的状态,然后用switch-case结构与双重for循环把它显示成对应的字符。接着,提示用户输入纵坐标与横坐标,在落子前还要先判断一下用户输入的坐标值是否超出范围。然后,再用原始又冗长的一长段判断语句,来判断有没有连成五子。虽然现在回看起来,那个判断条件真的是蠢萌蠢萌的,但当时的我真的是较劲了脑汁、使出了浑身解数,才想到了相对当时来说最高效的算法。
总的来说吧,那段时间还是挺快乐的,因为过得很充实,做这个做那个的,学到了很多,也创造了很多。但是呢,这个程序也暴露了当时的我编程的很多问题。比如,代码冗长,不懂得封装(因为还没有学到函数);比如,(现在看来)不必要的状态指示变量太多了,结构过于复杂。
基于以上种种问题,我决心把我的这个五子棋小程序从头再写一遍。利用后来所学的知识,该优化规格的优化规格,该优化代码的优化代码,该优化算法的优化算法。于是就做成了这篇文章所介绍的,我的新版本(2021版)五子棋小程序。

2、项目规格

【外部规格】
界面表现形式:CUI
操作方法:通过WSAD键控制光标上下左右移动,按空格键落子。
对战形式:仅可进行双人单机对战。无法进行人机对战、联网对战模式。
异常处理:当要落子的坐标上已经有棋子时,会报错提醒玩家重新落子。
回合制:否。该版本暂时为一回合游戏。胜负分晓即结束游戏。
BUG情况:最新版本中暂未发现BUG

【内部规格】
开发所用语言:C语言
代码总行数:195行
函数总数:6个(包括main函数)

3、核心算法

本程序用以检验是否连成五子的算法为,当棋手按下空格键落下棋子后即判定。以棋手落子位置为原点,首先进行x轴方向的判定:判断其本身与左侧4坐标点、右侧4坐标点,合计9个坐标点的范围内是否存在连续的五个子。具体的方法是,定义一个stoneCounter变量(初始值设作0),用以计数目标棋子在指定范围内连续出现了多少次。用for循环遍历这9个位置,每遇到一个目标棋子,stoneCounter++。但凡遇到一个非目标棋子的点,stoneCounter就立刻清零,从下一次再遇到目标棋子时开始重新计数。如果stoneCounter的值一旦达到了5,则立刻终止循环(注意:检测到五子连珠后立即终止循环很重要,否则容易出现BUG,导致明明已经五子了却判定为没有赢。因为,如果不停下来,而五子后面还有待检测的坐标,与目标棋子的代码不一致的话,stoneCounter就会清零,显示没有找到连续的五个子),返回肯定的判定结果给main函数,主程序就知道这名棋手胜利了。而如果遍历完9个位置,stoneCounter却始终没有到达过5,则说明检测范围内没有出现五子连珠。以此类推,y轴方向、函数y=x图像所在直线方向、函数y=-x图像所在直线方向亦然。

在这里插入图片描述

4、源代码

#include <stdio.h>
#include <stdlib.h>	//要调用系统命令,需要导入stdlib.h头文件
#include <conio.h>	//要接收键盘事件,需要导入conio.h头文件

#define X 1
#define O 2

char toSymbol(int num){
   		//函数作用:给定一个棋盘位置的状态值,返回这个状态值所对应的图形符号
	switch(num){
   		//其实本来是想用实心圆●表示黑棋,用空心圆⭕表示白棋的,但这次下的这个编译器似乎不太允许这样,显示出来全是乱码,于是只好改用X和O。
		case 0:
			return '.';		//空交叉点
		case X:
			return 'X';		//棋子X
		case O:
			return 'O';		//棋子O
		case 9:
			return '+';		//星位
	}
}

int check_hor(int panel[][15], int y, int x, int object){
   	//检查x轴方向上是否连成五子
	int stoneCount = 0;
	for(int i = x-4; i<=x+4; i++){
   
		if(panel[y][i]==object){
   
			stoneCount++;
			if(stoneCount == 5){
   
				break;
			}
		}else{
   
			stoneCount = 0;
		}
	}
	if(stoneCount >= 5){
   
		return 1;
	}else{
   
		return 0;
	}
}

int check_ver(int panel[][15], int y, int x, int object){
   	//检查y轴方向上是否连成五子
	int stoneCount = 0;
	for(int i = y-4; i<=y+4; i++){
   
		if(panel[i][x]==object){
   
			stoneCount++;
			if(stoneCount==5){
   
				break;
			}
		}else{
   
			stoneCount = 0;
		}
	}
	if(stoneCount >= 5)
  • 31
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
好的,我可以为您提供一个简单的五子棋程序的C语言代码示例,如下所示: ```c #include <stdio.h> #define SIZE 15 // 棋盘大小 int board[SIZE][SIZE]; // 棋盘 void init_board() { int i, j; for (i = 0; i < SIZE; i++) { for (j = 0; j < SIZE; j++) { board[i][j] = 0; // 初始化棋盘 } } } void print_board() { int i, j; printf(" "); for (i = 0; i < SIZE; i++) { printf("%2d", i + 1); } printf("\n"); for (i = 0; i < SIZE; i++) { printf("%2d", i + 1); for (j = 0; j < SIZE; j++) { if (board[i][j] == 0) { printf(" ."); // 空位 } else if (board[i][j] == 1) { printf(" X"); // 黑子 } else { printf(" O"); // 白子 } } printf("\n"); } } int check_win(int x, int y, int player) { int i, j, k; int count = 1; // 水平方向 for (i = y - 1; i >= 0 && board[x][i] == player; i--) { count++; } for (i = y + 1; i < SIZE && board[x][i] == player; i++) { count++; } if (count >= 5) { return 1; } // 垂直方向 count = 1; for (i = x - 1; i >= 0 && board[i][y] == player; i--) { count++; } for (i = x + 1; i < SIZE && board[i][y] == player; i++) { count++; } if (count >= 5) { return 1; } // 左上 - 右下方向 count = 1; for (i = x - 1, j = y - 1; i >= 0 && j >= 0 && board[i][j] == player; i--, j--) { count++; } for (i = x + 1, j = y + 1; i < SIZE && j < SIZE && board[i][j] == player; i++, j++) { count++; } if (count >= 5) { return 1; } // 右上 - 左下方向 count = 1; for (i = x - 1, j = y + 1; i >= 0 && j < SIZE && board[i][j] == player; i--, j++) { count++; } for (i = x + 1, j = y - 1; i < SIZE && j >= 0 && board[i][j] == player; i++, j--) { count++; } if (count >= 5) { return 1; } return 0; } void play_game() { int x, y; int player = 1; while (1) { printf("Player %d's turn:\n", player); printf("Enter x y: "); scanf("%d %d", &x, &y); x--; // 数组下标从0开始 y--; if (x < 0 || x >= SIZE || y < 0 || y >= SIZE) { printf("Invalid position!\n"); continue; } if (board[x][y] != 0) { printf("Position occupied!\n"); continue; } board[x][y] = player; print_board(); if (check_win(x, y, player)) { printf("Player %d wins!\n", player); break; } player = 3 - player; // 切换玩家 } } int main() { init_board(); print_board(); play_game(); return 0; } ``` 该程序实现了一个简单的五子棋游戏,包括棋盘的初始化、打印、玩家输入落子位置、落子、判断胜负等功能。请注意,该程序并没有实现任何 AI 算法,仅供参考。
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值