C语言实现简易五子棋小游戏

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

效果图如下:

设计思路:

棋盘设计为15×15格,初始状态光标在棋盘的中央,白棋先走,轮流落子,当一方连成五子或下满棋盘时,游戏结束(连成五子的一方获胜,下满棋盘为和棋)。当游戏一方胜利后显示胜利信息,提示信息利用汉字点阵输出。
程序游戏是一个二维平面图,可用二维数组来实现,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋格上的状态,共有三种情况,分别是0代表空格,1代表白棋,2代表黑棋。程序的主要工作是接收棋手按键操作,棋手1用设定四个键控制光标移动,回车键表示落子。棋手2用另四个键控制光标移动,空格键表示落子。接收到回车键或空格键,说明棋手落子,先判断是否是有效位置,即有棋子的位置不能重叠落子。落子成功后,马上判断以该位置为中心的八个方向:上、下、左、右、左上、左下、右上、右下是否有相同颜色的棋子连成五子,如果连成五子,则游戏结束。

#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#pragma comment(lib, "WINMM.LIB")
#include <mmsystem.h>
#include<conio.h>
#include<time.h>

#define width 32 //棋盘总宽度
#define high 31  //棋盘总高度
#define MAX_X 15 //棋盘横向格子数
#define MAX_Y 15 //棋盘纵向格子数
#define WIDTH (16+width) //游戏总高度
#define HIGH (high+4)    //游戏总高度
#define player1 1 //白子玩家
#define player2 2 //黑子玩家
#define emptyPlayer 0//无子
#define Unplayer -2 //中途退出游戏,无玩家获胜

typedef struct Stack{
    //记录下每次落子的坐标
 int x[MAX_X*MAX_Y];
 int y[MAX_X*MAX_Y];
 //相当于栈顶指针
 int top;
}Stack;

int pos[MAX_X][MAX_Y];//存储棋盘上各位置处的状态 比如有白子为1, 有黑子为2,无子为0
int px,py; //光标位置
int player = 1;//记录当前玩家 默认玩家从白方开始
int flag1 = 0;//标志游戏开始
int gameOver_player = -1;//判断结束的标志
int pre_px = -1, pre_py = -1;//记录下上一次的坐标位置

void gotoxy(int x,int y);//设置CMD窗口光标位置
void hide_cursor(); //隐藏CMD窗口光标
void map();//打印地图
void game_Description();//打印动态游戏说明
void initMapState();//初始化游戏位置数据
void mapState(int qizi);//数组记录下对应位置的状态
int isGoPlay();//判断是否可以落子
int hasGoPlay(int Player);//以落子处为中心,判断已经落子后的棋盘是否五子相连
void goPlay(int Player, Stack* p);//落子 Player 1 2 0
void yiDongKuang();//移动框
void player1_move();//玩家1_移动
void player2_move();//玩家2_移动
int gameOver();//判断游戏是否结束
Stack* createStack();//创建空栈
void push(Stack* p, int x, int y);//入栈
void color(const unsigned short textColor);//自定义函根据参数改变颜色
//void setColor(unsigned short backColor);//设置游戏背景颜色 

void gotoxy(int x,int y)//设置CMD窗口光标位置
{
 COORD coord;
 coord.X = x;
 coord.Y = y;
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

void hide_cursor() //隐藏CMD窗口光标
{
    CONSOLE_CURSOR_INFO cci;
    cci.bVisible = FALSE;
    cci.dwSize = sizeof(cci);
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorInfo(handle, &cci);
}

void color(const unsigned short textColor) //自定义函根据参数改变颜色
{
    if(textColor>0 && textColor<=15)     //参数在0-15的范围颜色
         SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), textColor);  //用一个参数,改变字体颜色
    else   //默认的字体颜色是白色
        SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}

//打印地图
void map()
{
    int x, y;
    color(02);
 /*开始打印棋盘格子*/
 //打印横向图格
 for(y = 2; y < high - 1; y+=2){
    for(x = 1; x < width - 2; x+=2){
           gotoxy(x , y);
     printf("-+");
      }
 }
 //打印竖向图格
 for(y = 1; y < high; y += 2) {
  for(x = 2; x < width-2; x += 2){
     gotoxy(x , y);
     printf("|");
  }
 }
 /*打印棋盘格子结束*/   

  /*开始打印图框*/ 

  //打印棋盘图框
 for (y = 0; y < high; y++)
 {
  for (x = 0; x < width; x+=2)
  {
   if (x == 0 ||  x == width - 2){
    gotoxy(x, y);
      printf("|");
   }
   if(y == 0 || y == high - 1 ){
    gotoxy(x, y);
      printf("--");
   }
  }
 }
 //打印右图框
 for(y = 0; y < high; y++){
  for(x = width; x < WIDTH; x+=2){
      if (x == WIDTH - 2){
    gotoxy(x, y);
      printf("|");
   }
   if(y == 0 || y == high - 1 ){
    gotoxy(x, y);
      printf("--");
   }
  }
 }
 //打印下图框 y->high ~ HiGH-1 x->0 ~ WIDTH-2
 for(y = high; y < HIGH; y++){
  for(x = 0; x < WIDTH; x+=2){
         if (x == 0 || x == WIDTH - 2){
    gotoxy(x, y);
      printf("|");
   }
   if(y == high || y == HIGH - 1 ){
    gotoxy(x, y);
      printf("--");
   }
  }
 }
    //打印下图框内容
    gotoxy( 1, high+1);
    printf("           欢迎来到五子棋游戏!");

 //打印右图框内容
 gotoxy( width-1, 1);
 printf("游戏说明:");
 gotoxy( width-1, 3);
 printf("1)X表示玩家一棋");
 gotoxy( width-1, 4);
 printf("子,而O表示玩家");
 gotoxy( width-1, 5);
 printf("二棋子");
 gotoxy( width-1, 7);
 printf("2)X先、O后,交替");
 gotoxy( width-1, 8);
 printf("下子,每次只能下");
 gotoxy( width-1, 9);
 printf("一子");
 gotoxy( width-1, 11);
 printf("3)棋子下在棋盘");
 gotoxy( width-1, 12);
 printf("的格子内,棋子下");
 gotoxy( width-1, 13);
 printf("定后,不得向其它");
    gotoxy( width-1, 14);
 printf("点移动");
    gotoxy( width-1, 16);
 printf("4)最先连成五子");
    gotoxy( width-1, 17);
 printf("的一方即为获胜");

 gotoxy( width-1, 19);
 printf("玩家一 移动键:");
    gotoxy( width-1, 20);
 printf("w上 s下 a左 d右");
 gotoxy( width-1, 21);
 printf("下子: 空格键");

 gotoxy( width-1, 23);
 printf("玩家二 移动键:");
    gotoxy( width-1, 24);
 printf("i上 k下 j左 l右");
 gotoxy( width-1, 25);
 printf("下子:回车键");   

    gotoxy( width+1, 27);
    color(4);
 printf("退出键: Y");
 gotoxy( width+1, 29);
 color(6);
 printf("悔棋键: G");
 /*打印图框结束*/
 color(02);
 /*打印棋盘上的四个标记点*/
     gotoxy( 3*2+2 , 3*2+2);
     printf("*");
     gotoxy( (MAX_X-4)*2 , 3*2+2);
     printf("*");
  gotoxy( 3*2+2 , (MAX_Y-4)*2);
     printf("*");
     gotoxy( (MAX_X-4)*2 , (MAX_Y-4)*2);
     printf("*");
 /*打印结束*/

 /*开始修边*/
 /*gotoxy(width - 1, 0);
 printf(" ");
 gotoxy(width - 1, high - 1);
 printf(" ");*/
 /*修边结束*/ 

   /*打印地图完成*/

}

//打印动态游戏说明
void game_Description()
{
    //打印下图框内容
    gotoxy( 1, high+1);
    printf("                               ");

 if(player == player1){
       gotoxy( 1, high+1);
       color(2);
    printf("             玩家一下棋中...");
 }else if(player == player2){
    gotoxy( 1, high+1);
    color(2);
    printf("             玩家二下棋中...");
 }

}
//初始化游戏位置数据
void initMapState()
{
 for(int i = 0 ; i < MAX_Y; i++){
  for(int j = 0; j < MAX_X; j++){
   pos[i][j] = 0;//初始状态全为空
  }
 }

 //注意 光标的位置和存储在数组中的位置是不同的
 px = 7;
 py = 7;

 gotoxy(py*2+1,px*2+1);//初始位置
}
//数组记录下对应位置的状态
void mapState(int qizi)
{ //2*px+1 = x //2*py+1 = y //px->0~14 //py->0~14
   if(px >= MAX_X || px < 0 || py >= MAX_Y || py < 0)
       return;//其他情况不可以记录状态 

   pos[px][py] = qizi;
}

//判断是否可以落子
int isGoPlay()
{
 if(px >= MAX_X || px < 0 || py >= MAX_Y || py < 0)
       return 0;//其他情况不可以记录状态

 if(pos[px][py] == emptyPlayer){//说明无子
  return 1;
 }else{//说明有子
  return 0;
 }

}
//以落子处为中心,判断已经落子后的棋盘是否五子相连
int hasGoPlay(int Player)
{   //分为两部分,先记录一部分的相同Player的个数
    //再记录下另余部分的个数,相加为相连棋子总个数
 int port1 = 0, port2 = 0;
 int x, y, count;
 //上下查找
 x = px, y = py-1;
 while(pos[x][y]==Player && y >= 0){
  ++port1;//上部分个数
  --y;//上移
 }
 y = py+1;
 while(pos[x][y]==Player && y < MAX_Y){
  ++port2;//下部分个数
  ++y;//下移
 }
 //计算总数
 count = port1 + port2 + 1;
 if(count >= 5) return 1; 

 //左右查找
 port1 = 0, port2 = 0;
    x = px-1, y = py;
 while(pos[x][y]==Player && x >= 0){
  ++port1;//上部分个数
  --x;//左移
 }
 x = px+1;
 while(pos[x][y]==Player && x < MAX_X){
  ++port2;//下部分个数
  ++x;//右移
 }
 //计算总数
 count = port1 + port2 + 1;
 if(count >= 5) return 1; 

 //左上右下查找
 port1 = 0, port2 = 0;
    x = px-1, y = py-1;
 while(pos[x][y]==Player && x >= 0 && y >= 0){
  ++port1;//上部分个数
  --x;//左移
  --y;//上移
 }
 x = px+1, y = py+1;
 while(pos[x][y]==Player && x < MAX_X && y < MAX_Y){
  ++port2;//下部分个数
  ++x;//右移
  ++y;//下移
 }
 //计算总数
 count = port1 + port2 + 1;
 if(count >= 5) return 1;  

  //右上左下查找
 port1 = 0, port2 = 0;
    x = px+1, y = py-1;
 while(pos[x][y]==Player && x < MAX_X && y >= 0){
  ++port1;//上部分个数
  ++x;//左移
  --y;//上移
 }
 x = px-1, y = py+1;
 while(pos[x][y]==Player && x >= 0 && y < MAX_Y){
  ++port2;//下部分个数
  --x;//右移
  ++y;//下移
 }
 //计算总数
 count = port1 + port2 + 1;
 if(count >= 5) return 1;  

 return 0;
}

//落子 Player 1 2 0
void goPlay(int Player, Stack* p)
{
     if(isGoPlay()){//说明可以落子
        mapState(Player);//将对应位置的情况记录在数组中 

        if(hasGoPlay(Player)){//如果五子相连,则 gameover
       gameOver_player = Player;  //记录此刻胜利玩家,结束游戏
       } 

           /*入栈*/
              push(p, px, py);

        /*角色切换*/
           if(Player == player1){
            player = player2;//切换成玩家1
             gotoxy(px*2+1, py*2+1 );//将光标移动到对应位置
                      color(07);
       printf("X");//打印玩家1
                      game_Description();// 动态说明
              }else if(Player == player2){
                      player = player1;//切换成另一个玩家2
                      gotoxy( px*2+1, py*2+1);//将光标移动到对应位置
             color(07);
       printf("O");//打印玩家2
             game_Description();// 动态说明
              }

    }
}

//入栈
void push(Stack* p, int x, int y)
{
 //将此刻的坐标入栈
    int top = p->top;
 ++p->top;//移动栈针

 p->x[top] = x;
 p->y[top] = y;

 return;
}
//出栈
void pop(Stack* p)
{
 int x, y;
 //出栈,移动栈顶指针
    //如果栈为空,则不弹出
    if(p->top <= 0) return;

 --p->top;
    int top = p->top;
    //记录下弹出的位置
    x = p->x[top];
    y = p->y[top];
 //在弹出位置打印空格
 gotoxy(x*2+1, y*2+1);
 printf(" ");
 //抹除记录
 pos[x][y] = 0;
}

//移动框
void yiDongKuang()
{
    //打印移动框
 gotoxy(px*2, py*2+1);
 color(11);
 printf("[");
 gotoxy(px*2+2, py*2+1);
 printf("]");
    //打印移动框结束
    if(pre_px != -1 && pre_py != -1){
  if(pre_px > px && pre_py == py){//当向左移动时
   //将上一个位置的右边保持原样
   gotoxy(pre_px*2+2, pre_py*2+1);
   color(2);
      printf("|");
  }else if(pre_px < px && pre_py == py){//当向右移动时
   //将上一个位置的左边保持原样
   gotoxy(pre_px*2, pre_py*2+1);
   color(2);
      printf("|");
  }else{//当向上下移动时
      //将上一个位置的左右边保持原样
   gotoxy(pre_px*2+2, pre_py*2+1);
      color(2);
   printf("|");
   gotoxy(pre_px*2, pre_py*2+1);
      color(2);
   printf("|");
  }
    }
    pre_px = px;
    pre_py = py;
}

//玩家1 移动
void player1_move(Stack* p)
{
 char key;
 if (_kbhit())//检测是否按键
 {
  fflush(stdin);
  key = _getch();//保存按键
  game_Description();//动态说明
 }

 switch(key)
 {
  case 'w': py--;yiDongKuang();break;//上
  case 'a': px--;yiDongKuang();break;//左
  case 'd': px++;yiDongKuang();break;//右
  case 's': py++;yiDongKuang();break;//下
   case ' ': goPlay(player1, p);break;//落子
     case 'y': gameOver_player = -2; gameOver();//退出游戏
      case 'Y': gameOver_player = -2; gameOver();//退出游戏
      case 'g': pop(p); pop(p); break;//悔棋
      case 'G': pop(p); pop(p); break;//悔棋
     default: break;
 }
 //限制光标范围
 if(py < 0) py = MAX_Y-1;
 else if(py >= MAX_Y) py = 0;
 else if(px < 0) px = MAX_X-1;
 else if(px >= MAX_X) px = 0;

 gotoxy(2*py+1, 2*px+1);
}
//玩家2 移动
void player2_move(Stack* p)
{
 char key;
 if (_kbhit())//检测是否按键
 {
  fflush(stdin);
  key = _getch();//保存按键
  game_Description();//动态说明
 }

 switch(key)
 {
   case 'i': py--;yiDongKuang();break;//上
     case 'j': px--;yiDongKuang();break;//左
   case 'l': px++;yiDongKuang();break;//右
   case 'k': py++;yiDongKuang();break;//下
   case '\r': goPlay(player2, p);break;//落子
  case 'y': gameOver_player = -2; gameOver();//退出游戏
  case 'Y': gameOver_player = -2; gameOver();//退出游戏
     case 'g': pop(p); pop(p); break;//悔棋
      case 'G': pop(p); pop(p); break;//悔棋
   default: break;
 }  

 //限制光标范围
 if(py < 0) py = MAX_Y-1;
 else if(py >= MAX_Y) py = 0;
 else if(px < 0) px = MAX_X-1;
 else if(px >= MAX_X) px = 0;

    gotoxy(2*px+1, 2*py+1);
}
//创建空栈
Stack* createStack(){
 //申请空间
 Stack* p = (Stack* )malloc(sizeof(Stack));
 //如果未申请到空间
 if(p==NULL) return NULL;

 p->top = 0;//初始化栈顶
    return p;
}

//判断游戏是否结束
int gameOver()
{    //gamerOver_player -1 表示继续游戏 1 表示白方胜利 2 表示黑方胜利 0 表示平局
    //五子相连 一方取胜 y->high ~ HiGH-1 x->0 ~ WIDTH-2
    if(gameOver_player == -1){
     return 1;
    }else if(gameOver_player == player1){//白方胜利
    gotoxy( 1, high+1);
       printf("玩家1胜利!!!");
       return 0;
 }else if(gameOver_player == player2){//黑方胜利
       gotoxy( 1, high+1);
    printf("玩家2胜利!!!");
    return 0;
 }else if(gameOver_player == emptyPlayer){//棋盘满棋 平局
       gotoxy( 1, high+1);
    printf("平局!!!");
    return 0;
 }else if(gameOver_player == Unplayer){//中途退出
       gotoxy( 1, high+1);
    printf("正在退出游戏中...");
    exit(1);
 }
 return 1;
}

int main(){

//调整游戏框
    system("mode con cols=48 lines=35");
//打印地图
    map();
//初始化游戏位置数据
 initMapState();
//创建空栈
    Stack* p = createStack();
//隐藏光标
 hide_cursor();
//游戏循环 控制移动
 while(gameOver()){
  //不断调换人物
      if(player == player1)
     player1_move(p);// 切换玩家1
   else if(player == player2)
     player2_move(p);// 切换玩家2
 }  

 free(p);
}

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

(0)

相关推荐

  • 基于C语言实现简单五子棋游戏

    本文实例为大家分享了C语言实现简单五子棋游戏的具体代码,供大家参考,具体内容如下 五子棋大家都玩儿过,所以规则就不介绍了 今天遇到一个学弟在实现的时候遇到一些问题,所以将实现的过程记录下 水平有限,仅供参考,互相交流,共同进步. #include<stdio.h> #include<windows.h>   int main() {       int i,j;//表示棋盘横纵坐标     /*********************************************

  • C语言实现五子棋小游戏

    首先我们先来看一个稍微简单些的实现方式: #include <stdio.h> #include <stdlib.h> #define N 15 int chessboard[N + 1][N + 1] = { 0 }; int whoseTurn = 0; void initGame(void); void printChessboard(void); void playChess(void); int judge(int, int); int main(void) { init

  • 基于C语言实现五子棋游戏

    采用二维数组制作五子棋,用坐标下棋. 请看代码. include<stdio.h> #include<string.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #include<time.h> void menu()//目录 { char xuanze = 0,xuanze2; printf("\n"); printf("\n&q

  • C语言实现简易五子棋

    本文实例为大家分享了C语言实现简易五子棋的具体代码,供大家参考,具体内容如下 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<time.h> #define ROW 5 #define COL 5 char g_broad[ROW][COL]; void menu(); void menu() { printf("--------------------

  • C语言编写五子棋游戏

    本文实例为大家分享了C语言编写五子棋游戏的具体代码,供大家参考,具体内容如下 一.构建棋盘 首先可以用一个二维数组来构建棋盘,下标表示位置,内容表示黑子白子或者空位.当数组内容为1时,该位置为白字,当数组为0时,该位置为白子,空位输出+ int w[11][11], flag = 0; int a, b; for (int k = 0; k < 11; k++) printf("第%d列\t", k); printf("\n"); for (int i = 0

  • 基于C语言实现五子棋游戏完整实例代码

    本文实例讲述了基于C语言实现五子棋游戏的方法,代码备有比较完整的注释,可以帮助读者更好的加以理解. 五子棋游戏代码如下: /* * 使用键盘的上下左右键移动棋盘,空格键表示下棋,ESC键退出程序 */ #include <stdio.h> #include <stdlib.h> #include <bios.h> #include <graphics.h> #include<malloc.h> /* * 对应键盘键的十六进制数字 */ #defi

  • C语言实现简单五子棋小游戏

    五子棋简单功能实现,供大家参考,具体内容如下 游戏功能演示 代码如下: #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <getch.h> // 棋盘 char board[15][15]; // 棋子坐标 char kx = 7 , ky = 7; // 角色 char role = '@'; // 显示棋盘 void show_board(void) { syste

  • C语言实现五子棋人人对战

    利用简单的c语言基础实现最简单的功能,界面比较丑陋主要是刚学完c的一个小实践,未使用MFC所以界面没有很好看 ,主要目的加强对c语言的理解与运用,同时增加自己的代码量. 首先要学一些头文件可以看我的博客前面的文章 要用到到的头文件stdio.h stdlib.h windows.h time.h conio.h 思路就是 1.画个棋盘,使用数组来代替初始化出* 2.使用循环使双方轮流下棋,使用数组存放棋子的位置 3.判断是否有一方获胜 首先打印棋盘 #include<stdio.h> #inc

  • 纯C语言实现五子棋

    正在考虑增加一个MFC界面.不是人机对战的. 五子棋.c //date 2014年7月7日09:53:24 //willows //五子棋 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <assert.h> //棋盘初始化函数 //Chessboard棋盘数组,ln=棋盘大小,成功返回Chessboard,不成功NULL void init_Chessboa

  • C语言实现五子棋游戏

    本文实例为大家分享了C语言实现五子棋的具体代码,供大家参考,具体内容如下 #include <stdio.h> #include <bios.h> #include <ctype.h> #include <conio.h> #include <dos.h> #define CROSSRU 0xbf /*右上角点*/ #define CROSSLU 0xda /*左上角点*/ #define CROSSLD 0xc0 /*左下角点*/ #defin

随机推荐