生命游戏新版
将原来的代码整理了一下,添加了“命令模式”
#include<cstdio>
#include<windows.h>
#include<ctime>
#include<conio.h>
class pubdata//public data
{
public:
static const int
maxh=17,// 高度
maxw=69, //宽度
maxharr=maxh+10,
maxwarr=maxw+10;
static const int
code_unknown=-1,//不知道死活
code_life=1,//生
code_dead=0;//死
static const char
show_life='*',
show_dead=' ';
static int cyclecnt,
update_waitms,
maxcells;//初始活细胞
static int map[maxharr][maxwarr],//细胞分布图
firstmap[maxharr][maxwarr];//初始的细胞分布图
};
int pubdata::cyclecnt = 0,
pubdata::update_waitms = 200,
pubdata::maxcells = 500;
int pubdata::map[pubdata::maxharr][pubdata::maxwarr];
class sysio
{
public:
static void io_hidecur(){//隐藏光标
CONSOLE_CURSOR_INFO cursor_info={1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cursor_info);
}
static void cleanscr(){
system("cls");
}
static void pause(){
system("pause>nul");
}
static int randrange(int l, int r)
{
//rand()%r-l+1 :[0, r-l]
//+l:[l, r]
return rand()%(r-l+1)+l;
}
static void getrand(int &x,int &y){
x = randrange(1, pubdata::maxh), y = randrange(1, pubdata::maxw);
}
static void cleanline(int line)
{
gotoxy(0,line);
printf(" ");
gotoxy(0, line);
}
static void gotoxy(int x,int y){ //光标移动到(x,y)位置
HANDLE handle=GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X=x;
pos.Y=y;
SetConsoleCursorPosition(handle,pos);
}
static void sleep(int timems)
{
Sleep(timems);
}
};
class bcfg//basic_config
{
public:
static void arrayset(int val){//给整个数组赋值成val
for(int i=0;i<pubdata::maxharr;++i){
for(int j=0;j<pubdata::maxwarr;++j){
pubdata::map[i][j]=val;
}
}
}
static bool is_inmap(int i,int j){//判断i,j是否在地图内
return 1 <= i && i <= pubdata::maxh && 1 <= j && j <= pubdata::maxw;
}
static int alivecnt(int i,int j){//该位置有几个活的生命
if(!is_inmap(i,j) || pubdata::map[i][j]!=pubdata::code_life) return 0;
return 1;
}
static int getneighbor(int x,int y){
static const int dx[] = {-1, 0, 1}, dy[] = {-1, 0, 1};
int ret = 0;
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
{
int nx = dx[i]+x, ny = dy[j]+y;
ret += alivecnt(nx, ny);
}
}
ret -= alivecnt(x, y);
return ret;
}
};
class show
{
public:
static void showinfo(){
printf("[LifeGame CDsidi Version 2.0.1 at 20200417]\n");
printf("[To Show the Reverence for Life, Hope Everything Will be Fine]\n");
printf("[Cycle:%d]\n",pubdata::cyclecnt);
}
static void showside(){
for(int i=0;i<=pubdata::maxw;++i)
printf("_");
printf("\n");
}
static void background(){
char s[]="生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机\n\
这个世界中的每个方格居住着一个活着的或死了的细胞。\n\
一个细胞在下一个时刻生死取决于相邻八个方格中活着的或死了的细胞的数量。\n\
如果相邻方格活着的细胞数量过多,这个细胞会因为资源匮乏而在下一个时刻死去;\n\
相反,如果周围活细胞过少,这个细胞会因太孤单而死去。\n\
在本版本游戏中,用'*'表示细胞";
MessageBox(NULL,TEXT(s),"游戏介绍",MB_OK);
}
static void showmap()//展示地图
{
for(int i=1;i<=pubdata::maxh;++i){
printf("|");
for(int j=1;j<=pubdata::maxw;++j){
if(pubdata::map[i][j]==pubdata::code_life)
printf("%c",pubdata::show_life);
else if(pubdata::map[i][j]==pubdata::code_dead){
printf("%c",pubdata::show_dead);
}else{
printf("?");
pubdata::map[i][j]=pubdata::code_dead;
}
}
printf("|\n");
}
}
static void showall(){
sysio::gotoxy(0,0);
showinfo();
showside();
showmap();
showside();
}
};
class ccfg//complex config
{
public:
static void refresh(){
int tmp[pubdata::maxharr][pubdata::maxwarr];
for(int i=1;i<=pubdata::maxh;++i){
for(int j=1;j<=pubdata::maxw;++j){
int neighbor=bcfg::getneighbor(i,j);//这样不会越界
if(neighbor==3)
tmp[i][j]=pubdata::code_life;
else if(neighbor==2)
tmp[i][j]=pubdata::map[i][j];
else
tmp[i][j]=pubdata::code_dead;
}
}
for(int i=1;i<=pubdata::maxh;++i){
for(int j=1;j<=pubdata::maxw;++j){
pubdata::map[i][j]=tmp[i][j];
}
}
}
};
class userio
{
public:
static void newhandinput()
{
show::background();
}
static void oldhandinput()
{
int a,b;
printf("[如果<=0 则采用默认值]");
printf("请输入在刷新图片间隔等待的时间(ms)\n");
scanf("%d",&a);
printf("请输入初始有生命的细胞最大个数\n");
scanf("%d",&b);
if(a > 0)pubdata::update_waitms = a;
if(b > 0)pubdata::maxcells = b;
}
static void input(){
int choose=MessageBox(NULL,TEXT("请问您是否第一次进行游戏?"),"游戏介绍",MB_OKCANCEL);
if(choose==1)
return newhandinput();
return oldhandinput();
}
static void initdata()
{
srand(time(0));
pubdata::cyclecnt = 0;
bcfg::arrayset(pubdata::code_unknown);
for(int i=1;i<=pubdata::maxcells;++i){
int x,y;
sysio::getrand(x,y);
pubdata::map[x][y]=pubdata::code_life;
}
}
static void initscr()
{
sysio::cleanscr();
sysio::io_hidecur();
system("title 生命游戏");
}
static void init(){
initscr();
initdata();
}
};
void solve();
class command
{
static const int
code_help = 1,
code_exit = 2,
code_replay = 3;
public:
static void cominput()
{
sysio::cleanline(pubdata::maxh+5);
int code;
printf("请输入命令代号:");
scanf("%d", &code);
comsolve(code);
sysio::cleanline(pubdata::maxh+5);
}
static void comhelp()
{
}
static void comexit(bool is_com)
{
sysio::cleanscr();
sysio::cleanline(0);
if(!is_com)printf("[ESC]");
else printf("[COM_EXIT]");
Sleep(1000);
exit(0);
}
static void comreplay(bool is_com)
{
sysio::cleanline(0);
if(!is_com)printf("[E][REPLAY]");
else printf("[COM_REPLAY][REPLAY]");
Sleep(1000);
sysio::cleanscr();
solve();
}
static void compause(bool is_com)
{
sysio::cleanline(0);
if(!is_com)printf("[KEYBORAD][PAUSE]");
else printf("[COM_DIFFAULT][PAUSE]");
sysio::gotoxy(0,pubdata::maxh+5);
printf("按任意键继续 ");
sysio::pause();
}
static void comsolve(int code)
{
switch(code)
{
case code_help:
comhelp();break;
case code_exit:
comexit(true);break;
case code_replay:
comreplay(true);break;
default:
compause(true);break;
}
}
};
void solve(){
userio::init();
while(kbhit());
while(1){
if(!kbhit()){
pubdata::cyclecnt++;
show::showall();
printf("按任意键暂停,按ESC退出,按E重新游戏,按C进入命令状态");
Sleep(pubdata::update_waitms);
ccfg::refresh();
}else{
int k=getch();
if(k==27){
command::comexit(false);
}else if(k=='e' || k == 'E'){
return command::comreplay(false);
}else if(k == 'C' || k == 'c')
{
command::cominput();
}else{
command::compause(false);
}
}
}
}
int main()
{
userio::input();
while(1)
{
solve();
}
return 0;
}```