三维圈夹游戏人机编程

                  三维圈夹游戏人机编程 

                            林清

游戏规则:市面上有一些三维的圈夹游戏商品,最常见的一种有4层透明塑料版,每层有4*4形式的洞。两人玩时轮流把有颜色的棋子放入空着的洞中,最先将4个同色的棋子连成一条线的人赢。连线的方式有许多种,可以是水平的、垂直的,或者有角度的。
分析:4个棋子共有76条可能连成的直线。每一层,与边平行的直线有8条,再加上2条对角线,所以每一层水平的直线就有10条,4层总共就有40条。还有16条垂直线,4条长对角线,以及在8个垂直面中,
每个面上的2条对角线。
设计方案:根据下此棋子的得分来判定:(以黑棋为例)
        (1):在一个空白的直线上加黑棋+1分
            在只有一个白棋的直线上加黑棋+2分
            在只有一个黑棋的直线上加黑棋+3分
            在有两个黑棋的直线上加黑棋+4分
            在有两个白棋的直线上加黑棋+5分
            在有三个黑棋的直线上加黑棋 一定执行。返回成功
            在有三个白棋的直线上加黑棋+100分
        (2):然后,下这个点的棋子影响的直线的得分总和如果最大的就下这个点。

给出代码:

//此版本不考虑图形的显示在很多属性没有纪录:
#include<stdio.h>
#include <process.h>
#include <ctype.h>
#define MAX 100

//pMatixLine[I][7]纪录了下这个点的棋子与76条直线的那条直线有关
int pMatixLine[64][7]=
{{1,5,9,41,57,61,69},{1,6,42,63,0,0,0},{1,7,43,65,0,0,0},{1,8,10,44,58,67,70},
{2,5,45,71,0,0,0},{2,6,9,46,0,0,0},{2,7,10,47,0,0,0},{2,8,48,72,0,0,0},
{3,5,49,73,0,0,0},{3,6,10,50,0,0,0},{3,7,9,51,0,0,0},{3,8,52,74,0,0,0},
{4,5,10,53,59,62,75},{4,6,54,64,0,0,0},{4,7,55,66,0,0,0},{4,8,9,56,60,68,76},
{11,15,19,41,0,0,0},{11,16,42,69,0,0,0},{11,17,43,70,0,0,0},{11,18,20,44,0,0,0},
{12,15,45,61,0,0,0},{12,16,19,46,57,63,71},{12,17,20,47,58,65,72},{12,18,48,67,0,0,0},
{13,15,49,62,0,0,0},{13,16,20,50,59,64,73},{13,17,19,51,60,66,74},{13,18,52,68,0,0,0},
{14,15,20,53,0,0,0},{14,16,54,75,0,0,0},{14,17,55,76,0,0,0},{14,18,19,56,0,0,0},
{21,25,29,41,0,0,0},{21,26,42,70,0,0,0},{21,27,43,69,0,0,0},{21,28,30,44,0,0,0},
{22,25,45,62,0,0,0},{22,26,29,46,60,64,72},{22,27,30,47,59,66,71},{22,28,48,68},
{23,25,49,61,0,0,0},{23,26,30,50,58,63,74},{23,27,29,51,57,65,73},{23,28,52,67,0,0,0},
{24,25,30,53,0,0,0},{24,26,54,76,0,0,0},{24,27,55,75,0,0,0},{24,28,29,26,0,0,0},
{31,35,39,41,60,62,70},{31,36,42,64,0,0,0},{31,37,43,66,0,0,0},{31,38,40,44,59,68,69},
{32,35,45,72,0,0,0},{32,36,39,46,0,0,0},{32,37,40,47,0,0,0},{32,38,48,71,0,0,0},
{33,35,49,74,0,0,0},{33,36,40,50,0,0,0},{33,37,39,51,0,0,0},{33,38,52,73,0,0,0},
{34,35,40,53,58,61,76},{34,36,54,63,0,0,0},{34,37,55,65,0,0,0},{34,38,39,56,57,67,75}};
typedef enum LineStyle{empty,oneblack,towblack,threeblack,onewhite,towwhite,threewhite,mix,succeed}MyLineStyle;
typedef enum ChessmanStyle{without,chessblack,chesswhite}MyChessmanStyle;
//typedef enum ChessmanStyle{without,have}MyChessmanStyle;
typedef enum CurrentChess{black,white}MyCurrentChess;
//实现根据chess的输入改变alllinestyle影响的线条状态和allchess棋子的状态以方便下此选择的过滤
//返回1成功
int ChangeState(int IFblack,MyLineStyle AllLineStyle[76],int chess,MyChessmanStyle AllChess[64]);
//计算如果下这位置的得分数
//变成有唯一一个自己的+1
//变成有二个的+3
//变成有三个的+4
//变成有四个的+max+1
//破坏对方三个的+max
//破坏对方一个的+2
//破坏对方二个的+5
//从本来就无用的变成有用的+0
//返回-1为成功,必选
int SingleCount(int IFblack,int chess,MyLineStyle AllLineStyle[76]);
//实现选择那个方案最理想返回下的棋子位置
//返回-1无棋子可下
int ProjectSelect(int IFblack,MyLineStyle AllLineStyle[76],MyChessmanStyle AllChess[64]);
//白棋用户的输入状态
int InputChess(int IFblack,MyChessmanStyle AllChess[64]);
//打印棋盘
int chessboard(MyChessmanStyle AllChess[64]);
//打印菜单
char menu();
//人-机游戏
int mantocomputer();
//单机版人与人游戏
int mantoman();
//游戏规则
int ReadMe();
int ChangeState(int IFblack,MyLineStyle AllLineStyle[76],int chess,MyChessmanStyle AllChess[64])
{
 int i;
 int curline;
 if (AllChess[chess]) {printf("Did not chance input ");return 0;}
// AllChess[chess]=have;
 if(IFblack)//白棋下
 { 
  AllChess[chess]=chesswhite;
  for(i=0;i<7&&pMatixLine[chess][i]!=0;i++)
  {
   curline=pMatixLine[chess][i]-1;
   switch(AllLineStyle[curline])
   {
   case empty:
    AllLineStyle[curline]=onewhite;
    break;
   case oneblack:
   case towblack:
   case threeblack:
    AllLineStyle[curline]=mix;
    break;
   case onewhite:
    AllLineStyle[curline]=towwhite;
    break;
   case towwhite:
    AllLineStyle[curline]=threewhite;
    break;
   case threewhite:
    AllLineStyle[curline]=succeed;
    return 1;
   case mix:
    break;
   }
  }
 }
 else//黑棋下
 {
  AllChess[chess]=chessblack;
  for(i=0;i<7&&pMatixLine[chess][i]!=0;i++)
  {
   curline=pMatixLine[chess][i]-1;
   switch(AllLineStyle[curline])
   {
   case empty:
    AllLineStyle[curline]=oneblack;
    break;
   case oneblack:
    AllLineStyle[curline]=towblack;
    break;
   case towblack:
    AllLineStyle[curline]=threeblack;
    break;
   case threeblack:
    AllLineStyle[curline]=succeed;
    return 1;
   case onewhite:
   case towwhite:
   case threewhite:
    AllLineStyle[curline]=mix;
   case mix:
    break;
   }
  }
 }
 return 0;
}

//计算如果下这位置的得分数
//变成有唯一一个自己的+1
//变成有二个的+3
//变成有三个的+4
//变成有四个的+max+1
//破坏对方三个的+max
//破坏对方一个的+2
//破坏对方二个的+5
//从本来就无用的变成有用的+0
//返回-1为成功,必选
int SingleCount(int IFblack,int chess,MyLineStyle AllLineStyle[76])
{
 int i;
 int curline;
 int sum=0;
 if(IFblack)//白棋下
 {
  for(i=0;i<7&&pMatixLine[chess][i]!=0;i++)
  {
   curline=pMatixLine[chess][i]-1;
   switch(AllLineStyle[curline])
   {
   case empty:
    sum=sum+1;
    break;
   case oneblack:
    sum=sum+2;
    break;
   case towblack:
    sum=sum+5;
    break;
   case threeblack:
    return MAX;
   case onewhite:
    sum=sum+3;
    break;
   case towwhite:
    sum=sum+4;
    break;
   case threewhite:
    return -1;
   case mix:
    break;
   }
  }
 }
 else//黑棋下
 {
  for(i=0;i<7&&pMatixLine[chess][i]!=0;i++)
  {
   curline=pMatixLine[chess][i]-1;
   switch(AllLineStyle[curline])
   {
   case empty:
    sum=sum+1;
    break;
   case oneblack:
    sum=sum+3;
    break;
   case towblack:
    sum=sum+4;
    break;
   case threeblack:
    return -1;
   case onewhite:
    sum=sum+2;
    break;
   case towwhite:
    sum=sum+5;
    break;
   case threewhite:
    sum=MAX;
    break;
   case mix:
    break;
   }
  }
 }
 return sum;
}
//实现选择那个方案最理想返回下的棋子位置
//返回-1无棋子可下
int ProjectSelect(int IFblack,MyLineStyle AllLineStyle[76],MyChessmanStyle AllChess[64])
{
 int downchess=-1;
 int maxmark=0;
 int currentmark=0;
 for(int i=0;i<64;i++)
 {
  if(AllChess[i]!=without) continue;
  currentmark=SingleCount(IFblack,i,AllLineStyle);
  if(currentmark==-1) return i;
  if(currentmark>maxmark)
  {
   downchess=i;
   maxmark=currentmark;
  }
 }
 return downchess;
}
//白棋用户的输入状态
int InputChess(int IFblack,MyChessmanStyle AllChess[64])
{
 int z,x,y;
 int chess;
 do
 {
  chessboard(AllChess);
  if(IFblack==black)printf("黑棋下%c(层,行,列):",1);
  else printf("白棋下%c(层,行,列):",2);
  scanf("%d,%d,%d",&z,&y,&x);
  chess=(z-1)*16+y*4+x;
 }while(z>4||z<1||y>3||y<0||x>3||x<0||AllChess[chess]!=without);
    return chess;
}
//打印棋盘
int chessboard(MyChessmanStyle AllChess[64])
{
 int i,j,m,current=0;
 system("cls");
 printf("         三维圈夹游戏/n");         
 printf("|(一)|  |(二)|  |(三)|  |(四)|/n");
 printf("|0123|  |0123|  |0123|  |0123|/n");
 for(i=0;i<4;i++)
 {
  for(j=0;j<4;j++)
  {
   printf("%d",i);
   for(m=0;m<4;m++)
   {
    switch(AllChess[current++])
    {
    case without: printf(" ");break;
    case chessblack:printf("%c",1);break;
    case chesswhite:printf("%c",2);break;
    }
   }
   printf("|  ");
   current=current+12;
  }
  printf("/n");
  current=(i+1)*4;
 }
 return 1;
}
//打印菜单
char menu()
{
 char ch;
 do
 {
  system("cls");
  printf("(J)人机模式/n");
  printf("(M)人-人模式/n");
  printf("(R)游戏规则/n");
  printf("(F)返回/n");
  printf("请选择你所要的操作(J,M,R,F):");
  scanf("%c",&ch);
     ch=toupper(ch);
 }while(ch!='J'&&ch!='M'&&ch!='R'&&ch!='R');
 return ch;
}
//人-机游戏
int mantocomputer()
{
 MyCurrentChess currentchess=black;
    MyLineStyle line[76];
 MyChessmanStyle chess[64];
 int GetChess=-1;
 int i;
 for(i=0;i<76;i++) line[i]=empty;
 for(i=0;i<84;i++) chess[i]=without;
//    chessboard(chess);
 do
 {
  if((GetChess=InputChess(currentchess,chess))==-1) {printf("Input error or exit/n");break;}
  if(ChangeState(currentchess,line,GetChess,chess)) {chessboard(chess);printf("black  win/n");break;}
  currentchess=white;
  if((GetChess=ProjectSelect(currentchess,line,chess))==-1){printf("a draw in chess/n");break;}
  if(ChangeState(currentchess,line,GetChess,chess)) {chessboard(chess);printf("white  win/n");break;}
  currentchess=black;
  chessboard(chess);
 }while(1);
 return 1;
}
//单机版人与人游戏
int mantoman()
{
 return 1;
}
//游戏规则
int ReadMe()
{
 return 1;
}
int main()
{
 char ch;
 do
 {
  ch=menu();
  switch(ch)
  {
  case 'J':
   mantocomputer();
   break;
  case 'M':
   mantoman();
   break;
  case 'R':
   ReadMe();
   break;
  case 'F':
   break;
  }
 }while(ch=='F');
 printf("/n欢迎使用/n");
 system("pause");
 return 1;
}

//备注:第一次发稿,请大家原谅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值