生命游戏源码

#include <iostream>
#include <vector>
#include <ege.h>

std::vector<std::vector<int> > livemap;
int width = 120, height = 80;//地图逻辑大小,表示有120*80个格子,每个格子表示一个细胞 
const int BSIZE = 10; //表示每个格子的边长为size大小的像素 
const int STARTLEFT = 100;//表示画方格边界时左上角的横坐标 
const int STARTRIGHT = 10;// 表示画方格边界时左上角的纵坐标
void mainloop();
int countlivecell(std::vector<std::vector<int> >& board, int x, int y);//计算坐标为x,y格子周围有几个存活的细胞 
void gameoflife(std::vector<std::vector<int> >& board);//更新整个地图的逻辑数据 
void drawlivemap();//显示整个地图 
void setlivemap(int x, int y);//编辑地图,使坐标包含x,y的格子点亮或熄灭 


int main(int argc, char** argv) {
	std::vector<int> t;
	for(int j = 0; j < height; ++j)
	{
		t.push_back(0);
	}
	
	for(int i = 0; i < width; ++i)
	{
		livemap.push_back(t);
	}
	
	ege::setinitmode(ege::INIT_DEFAULT|ege::INIT_NOFORCEEXIT);
	ege::initgraph(-1, -1);
	
	ege::setrendermode(ege::RENDER_MANUAL);
	
	mainloop();
	
	ege::closegraph();
	
	
	return 0;
}


void mainloop()
{
	ege::mouse_msg mousedata;
	bool isleftdown = false, flag = false;
	int x0, y0, x, y, t;
	for(; ege::is_run(); ege::delay_fps(60))
	{
		if(ege::kbhit()) 
		{
			ege::getch();
			break;
		}
		mousedata = ege::mouse_msg();
		while(ege::mousemsg())
		{
			mousedata = ege::getmouse();
			if(mousedata.is_left())
			{
				if(mousedata.is_down())
				{
					isleftdown = true;
					flag = true;
					x0 = mousedata.x;
					y0 = mousedata.y;
				}
				else if(mousedata.is_up())
				{
					isleftdown = false;
					x = mousedata.x;
					y = mousedata.y;
					if(x0 > x)
					{
						t = x0;
						x0 = x;
						x = t;
					}
					if(y0 > y)
					{
						t = y0;
						y0 = y;
						y = t;
					}
				}
			}
			
		}
		
		if(!isleftdown && flag)
		{
			for(int i = x0; i <= x; i+=BSIZE-1)
			{
				for(int j = y0; j <= y; j+=BSIZE-1)
				{
					setlivemap(i, j);
				}
			}
			flag = false;
			
		}
		
		
		ege::cleardevice();
		drawlivemap();
	}
	
	
	
	
	
	for(; ege::is_run(); ege::delay_fps(15))
	{
		//逻辑更新
		//
		gameoflife(livemap);
		
		
		
		//图形更新
		ege::cleardevice();
		drawlivemap();
	}
	
	
}

int countlivecell(std::vector<std::vector<int> >& board, int x, int y)
    {
        int res = 0;
        if(x - 1 >= 0 && board[x-1][y]) ++res;
        if(x - 1 >= 0 && y + 1 < board[0].size() && board[x - 1][y + 1]) ++res;
        if(y + 1 < board[0].size() && board[x][y + 1]) ++res;
        if(x + 1 < board.size() && y + 1 < board[0].size() && board[x + 1][y + 1]) ++res;
        if(x + 1 < board.size() && board[x + 1][y]) ++ res;
        if(x + 1 < board.size() && y - 1 >= 0 && board[x + 1][y - 1]) ++res;
        if(y - 1 >= 0 && board[x][y - 1]) ++res;
        if(x - 1 >= 0 && y - 1 >= 0 && board[x- 1][y - 1]) ++res;
        return res;
    }
    
void gameoflife(std::vector<std::vector<int> >& board) {
    int r = board.size(), c = board[0].size();
    std::vector<std::vector<int> > t;
    std::vector<int> row;
    for(int i = 0; i < r; ++i)
    {
        row.clear();
        for(int j = 0; j < c; ++j)
        {
            switch(countlivecell(board, i, j))
            {
                case 0:
                case 1:
                    row.push_back(0);
                    break;
                case 2:
                    row.push_back(board[i][j]);
                    break;
                case 3:
                    row.push_back(1);
                    break;
                case 4:
                case 5:
                case 6:
                case 7:
                case 8:
                    row.push_back(0);
            }
        }
        t.push_back(row);
    }
    board = t;
}

void drawlivemap()
{
	ege::setcolor(ege::hsl2rgb(120, 1, 0.05));
	ege::setfillcolor(ege::GREEN);
	int x, y;
	int mousex, mousey;
	ege::mousepos(&mousex, &mousey);
	int r, c;
	r = (mousex - STARTLEFT)/(BSIZE - 1);
	c = (mousey - STARTRIGHT)/(BSIZE - 1);
	for(int i = 0; i < width; ++i)
	{
		for(int j = 0; j < height; ++j)
		{
			if(i == 0) x = STARTLEFT + i * BSIZE;
			else x = STARTLEFT + i * BSIZE - i;
			
			if(j == 0) y = STARTRIGHT + j * BSIZE;
			else y = STARTRIGHT + j * BSIZE - j;
			ege::rectangle(x, y, x + BSIZE, y + BSIZE);
			if(livemap[i][j])
			{
				ege::floodfillsurface(x + 1, y + 1, ege::getbkcolor());
			}
		}
	}
	
	ege::setcolor(ege::hsl2rgb(120, 1, 0.2));
	if(r - 1 >= 0) 
	{
		x = STARTLEFT + (r - 1) * BSIZE - (r - 1);
		y = STARTRIGHT + c * BSIZE - c;
		ege::rectangle(x, y, x + BSIZE, y + BSIZE);	
	}
	if(r + 1 < width) 
	{
		x = STARTLEFT + (r + 1) * BSIZE - (r + 1);
		y = STARTRIGHT + c * BSIZE - c;
		ege::rectangle(x, y, x + BSIZE, y + BSIZE);
	}
	if(c - 1 >= 0) 
	{
		x = STARTLEFT + r * BSIZE - r;
		y = STARTRIGHT + (c - 1) * BSIZE - (c - 1);
		ege::rectangle(x, y, x + BSIZE, y + BSIZE);
	}
	if(c + 1 < height) 
	{
		x = STARTLEFT + r * BSIZE - r;
		y = STARTRIGHT + (c + 1) * BSIZE - (c + 1);
		ege::rectangle(x, y, x + BSIZE, y + BSIZE);
	}
	
	ege::setcolor(ege::hsl2rgb(120, 1, 0.5));
	x = STARTLEFT + r * BSIZE - r;
	y = STARTRIGHT + c * BSIZE - c;
	ege::rectangle(x, y, x + BSIZE, y + BSIZE);

}

void setlivemap(int x, int y)
{
	int r, c;
	int mousex = x, mousey = y;
	r = (mousex - STARTLEFT)/(BSIZE - 1);
	c = (mousey - STARTRIGHT)/(BSIZE - 1);
	
	if(livemap[r][c])
		livemap[r][c] = 0;
	else
		livemap[r][c] = 1;
}


评论区

张小三

2020-05-20 10:18

大佬NB