C语言实现简单井字棋游戏

 更新时间:2021年04月28日 09:30:23   作者:冰凌呀  
这篇文章主要为大家详细介绍了C语言实现简单井字棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

游戏截图

源代码

person.h

//玩家对战 
void person()
{
 int i,j;
 initMap(map);
 //打印棋局 
 displayMap(map);
 //未分出胜负且棋局未落满子前无限循环 
 while(1)
 {
  //获取玩家下子位置 
  getXY(&i,&j);
  //玩家落子
  setPiece(map,i,j);
  //清屏 
  system("cls");
  //打印棋局 
  displayMap(map);
  //玩家落子后判断是否已经分出胜负
  if(isWin(map)==1)
  {
   //输出获胜方 
   displayWinner();
   break;
  }
  //是否棋局已满 
  else if(count==row*col)
  {
   printf("平局!\n");
   break; 
  } 
  //交替到对手回合
  exchangeTurn(); 
 }
}

computer.h

//局面价值 
int getSum(char map[][col])
{
 int sumO=0,sumX=0;
 int i,j;
 for(i=0;i<row;i++)
 {
  for(j=0;j<col;j++)
  {
   if(map[i][j]=='O')
   {
    sumO+=score[i][j];
   }
   else if(map[i][j]=='X')
   {
    sumX+=score[i][j];
   }
  }
 }
 return sumX-sumO;
}

//思考
void think(char map[][col])
{
 int canWin=0;
 int i,j;
 int x=-1,y=-1;
 int sum;
 int maxSum=-20;
 count++;
 for(i=0;i<row;i++)
 {
  for(j=0;j<col;j++)
  {
   if(map[i][j]==m)
   {
    map[i][j]='X';
    
    //能获胜,直接落子此处 
    if(isWin(map))
    {
     return;
    }
    //不能获胜,落子在分数最多的地方 
    else
    {
     map[i][j]='O';
     if(isWin(map))
     {
      map[i][j]='X';
      return;
     }
     map[i][j]='X';
     sum=getSum(map);
     if(sum>maxSum)
     {
      maxSum=sum;
      x=i;
      y=j;
     }
    }
    
    map[i][j]=m; 
   } 
  }
 }
 map[x][y]='X'; 
}

void computer()
{
 int i,j;
 char computerType='X';
 initMap(map);
 //打印棋局 
 displayMap(map);
 //未分出胜负且棋局未落满子前无限循环 
 while(1)
 {
  //电脑落子 
  if(nowType==computerType)
  {
   printf("电脑落子:");
   think(map);
  }
  //玩家落子 
  else
  {
   //获取玩家下子位置 
   getXY(&i,&j);
   //玩家落子
   setPiece(map,i,j);
  }
 
  //清屏 
  system("cls");
  //打印棋局 
  displayMap(map);
  //玩家落子后判断是否已经分出胜负
  if(isWin(map)==1)
  {
   //输出获胜方 
   displayWinner();
   break;
  }
  //是否棋局已满 
  else if(count==row*col)
  {
   printf("平局!\n");
   break; 
  } 
  //交替到对手回合
  exchangeTurn(); 
 }
}

main.c

#include<stdio.h>
#include<stdlib.h>

//棋局
char map[3][3];
//行列
int row=3,col=3;
//棋子类型
char o='O',x='X',m=' ';
//当前棋子类型
char nowType='O'; 
//已落子数量
int count=0;

//初始化棋局 
void initMap(char map[][col])
{
 int i,j;
 for(i=0;i<row;i++)
 {
  for(j=0;j<col;j++)
  {
   map[i][j]=m;
  }
 }
}

//打印当前棋局 
void displayMap(char map[][col])
{
 int i,j;
 printf("   ");
 for(i=0;i<col;i++)
 {
  printf("%d ",i);
 }
 printf("\n  ");
 for(i=0;i<2*col+1;i++)
 {
  printf("*");
 }
 printf("\n");
 for(i=0;i<row;i++)
 {
  printf("%d  ",i);
  for(j=0;j<col;j++)
  {
   printf("%c ",map[i][j]);
  }
  printf("\n  ");
  for(j=0;j<2*col+1;j++)
  {
   printf("*");
  }
  printf("\n");
 }
}

//获取用户输入
void getXY(int *i,int *j)
{
 while(1)
 {
  printf("落子方:%c\n",nowType);
  printf("落子位置(x,y)=");
  scanf("%d %d",i,j);
  if(*i<0||*i>=row||*j<0||*j>=col||map[*i][*j]!=m)
  {
   printf("输入不合法!\n"); 
  } 
  else 
  {
   return;
  } 
 }
}

//交替下子
void exchangeTurn()
{
 if(nowType==o)
 {
  nowType=x;
 }
 else
 {
  nowType=o;
 }
}

//下子
void setPiece(char map[][col],int i,int j)
{
 map[i][j]=nowType;
 count++;
}

//判断是否分出胜负,分别从横竖斜三个方向数数 
int isWin(char map[][col])
{
 int i,j;
 int flagR,flagC;
 for(i=0;i<row;i++)
 {
  flagR=0,flagC=0;
  for(j=0;j<col;j++)
  {
   if(map[i][j]==o)
   {
    flagR++; 
   }  
   else if(map[i][j]==x)
   {
    flagR--;
   }
   if(map[j][i]==o)
   {
    flagC++;
   }
   else if(map[j][i]==x)
   {
    flagC--;
   }
  } 
  if(flagR==col||flagC==col||flagR==(-col)||flagC==(-col))
  {
   return 1;
  }
 } 
 flagR=0,flagC=0;
 for(i=0,j=0;i<row&&j<col;i++,j++)
 {
  if(map[i][j]==o)
  {
   flagR++;
  }
  else if(map[i][j]==x)
  {
   flagR--;
  }
  if(map[i][col-j-1]==o)
  {
   flagC++;
  }
  else if(map[i][col-j-1]==x)
  {
   flagC--;
  }
 }
 if(flagR==col||flagC==col||flagR==(-col)||flagC==(-col))
 {
  return 1;
 }
 else 
 {
  return 0;
 }
}

//输出胜方
void displayWinner()
{
 printf("%c方获得胜利!\n",nowType); 
}

//给局面打分的基础表(站位分) 
int score[3][3]={
 {4,2,4},
 {2,8,2},
 {4,2,4}
};
//引入自定义头文件 
#include"person.h"
#include"computer.h"
 
int main()
{
 int gameType;
 printf("1.人机对战\n其他.玩家对战\n");
 scanf("%d",&gameType);
 if(gameType==1)
 {
  computer();
 }
 else
 {
  person();
 } 
 return 0;
}

代码解析

1、 其实棋类游戏设计最重要的就是模拟下棋的过程。
2、 我们知道井字棋是双方交替下子,一方执O,一方执X。
3、 比如O先下,玩家下完子后,我们判断一下此时他是否已经获胜(即是否出现横或竖或两斜线出现三子连珠的情况),没有获胜则判断是否已经将棋局下满子了,还是没有的话,轮到X的回合。再次执行此步骤。
4、 了解了过程就自然好设计了。因为棋局比较简单,我们用一个二维字符数组即可存储。落子位置用坐标(x,y),通过玩家输入即可进行模拟。

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

相关文章

  • C语言之字符串模糊查询方法的实现

    C语言之字符串模糊查询方法的实现

    本篇文章主要为大家介绍字符串模糊查询的C语言程序编写方法,有需要的朋友可以参考下
    2015-07-07
  • c语言中main函数用法及知识点总结

    c语言中main函数用法及知识点总结

    在本篇文章里小编给大家分享的是一篇关于c语言中main函数用法及知识点总结内容,有需要的朋友们可以跟着学习参考下。
    2021-10-10
  • c语言中缺省参数的类型总结

    c语言中缺省参数的类型总结

    在本篇文章里小编给大家整理了一篇关于c语言中缺省参数的类型总结内容,有兴趣的朋友们可以跟着学习参考下。
    2021-09-09
  • C++ 智能指针代码解析

    C++ 智能指针代码解析

    这篇文章主要介绍了c++ 智能指针基础的相关资料,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下,希望能给你带来帮助
    2021-10-10
  • C/C++判断素数的三种方法

    C/C++判断素数的三种方法

    这篇文章主要给大家介绍了C/C++判断素数的三种方法,常规的函数判断法,埃氏筛法和欧拉筛法这三种方法,并通过代码示例讲解的非常详细,具有一定的参考价值,需要的朋友可以参考下
    2023-12-12
  • C语言通过栈实现小人走迷宫

    C语言通过栈实现小人走迷宫

    这篇文章主要为大家详细介绍了C语言通过栈实现小人走迷宫,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • C指针原理教程之AT&T汇编

    C指针原理教程之AT&T汇编

    AT&T 汇编是一种和intel汇编在语法上完全不同的汇编语言,为避免混淆intel语法,本文只介绍AT&T汇编,AT&T的第一个特点就是每个寄存器名前必须加‘%’,立即数前必须加‘$’
    2019-02-02
  • Qt使用Json的项目实践

    Qt使用Json的项目实践

    JSON是一种对源自Javascript的对象数据进行编码的格式,但现在被广泛用作互联网上的数据交换格式,本文主要介绍了Qt使用Json的项目实践,详细的介绍了主要使用的类以及Json实战,感兴趣的可以了解一下
    2023-09-09
  • 筛选法的C++实现

    筛选法的C++实现

    筛选法又称筛法,是求不超过自然数N(N>1)的所有质数的一种方法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛子
    2013-10-10
  • C++中宏的使用问题详解

    C++中宏的使用问题详解

    宏替换是C/C++系列语言的技术特色,C/C++语言提供了强大的宏替换功能,源代码在进入编译器之前,要先经过一个称为“预处理器”的模块,这个模块将宏根据编译参数和实际编码进行展开,展开后的代码才正式进入编译器,进行词法分析、语法分析等等。
    2016-05-05

最新评论