· 更新于 2017年11月11日 随笔

控制台小游戏合集(持续更新)

近日为了做好游戏相关的准备,特地自行制作了几款控制台的小游戏,在以后的时间中,也会持续更新。

目录

近日为了做好游戏相关的准备,特地自行制作了几款控制台的小游戏,在以后的时间中,也会持续更新。

五子棋(鼠标下棋)

#include <iostream>
#include <Windows.h>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;

#define LEFT_CLICK FROM_LEFT_1ST_BUTTON_PRESSED
#define RIGHT_CLICK RIGHTMOST_BUTTON_PRESSED
typedef int GameState;
#define PLAYING 0
#define BLACKWIN 1
#define WHITEWIN 2
#define BLACK 1
#define WHITE 2
int ChessBoard[19][19];
short Top = 3, Left = 6;
char BlackChess[3] = "○";
char WhiteChess[3] = "●";
int Direct[8][2] = {
	{ 1,1 },
	{ 1,0 },
	{ 1,-1 },
	{ 0,-1 },
	{ -1,-1 },
	{ -1,0 },
	{ -1,1 },
	{ 0,1 }
};
//------------------控制台函数------------------------
void curGotoXY(short x, short y);//光标移动
COORD getMouseXY(DWORD clickType);//鼠标单击时的位置 clickType = LEFT_CLICK时为鼠标左键
void HideCursor();
void ClearScreen(); // 清屏
void PrintInXY(short x, short y, char *str);
//-----------------------函数-----------------------
void ShowInfo(bool isBlack);
void ClearCB();
void DrawCB();
void Game();
GameState CheckWin(int x, int y);
void Message(int whoWin);

int main() {
	HideCursor();
	while(true){
		ClearScreen();
		ClearCB();
		DrawCB();
		Game();
		curGotoXY(0, 0);
		getchar();
	}
	return 0;
}

void curGotoXY(short x, short y) {
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { x,y });
}
COORD getMouseXY(DWORD clickType) {
	INPUT_RECORD inRec;
	DWORD res;
	COORD pos;
	while (1) {
		ReadConsoleInputW(GetStdHandle(STD_INPUT_HANDLE), &inRec, 1, &res);
		if (inRec.EventType == MOUSE_EVENT) {
			pos = inRec.Event.MouseEvent.dwMousePosition;
			if (inRec.Event.MouseEvent.dwButtonState == clickType)
				break;
		}
	}
	return pos;
}
void HideCursor() {
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void ClearScreen() {
	CONSOLE_SCREEN_BUFFER_INFO bInfo;
	DWORD d;
	GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &bInfo);
	COORD home = { 0, 0 };
	unsigned long size = bInfo.dwSize.X * bInfo.dwSize.Y;
	FillConsoleOutputCharacterW(GetStdHandle(STD_OUTPUT_HANDLE), 0, size, home, &d);
}
void PrintInXY(short x, short y, char * str) {
	//DWORD d;
	curGotoXY(x, y);
	printf_s("%s", str);
	//WriteConsoleOutputCharacter(GetStdHandle(STD_OUTPUT_HANDLE), (LPCWSTR)str, strlen(str), { x,y }, &d);
}

void ShowInfo(bool isBlack) {
	char * str;
	if (isBlack)str = "该黑棋下了";
	else str = "该白棋下了";
	PrintInXY(Left + 8, 2, str);
}
void ClearCB() {
	for (int i = 0; i < 19; i++)
		for (int j = 0; j < 19; j++)
			ChessBoard[i][j] = 0;
}
void DrawCB() {
	char * str;
	for (short i = 0; i < 19; i++) {
		for (short j = 0; j < 19; j++) {
			if (i == 0 && j == 0)
				str = "╔";
			else if (i == 0 && j == 18)
				str = "╚";
			else if (i == 18 && j == 0)
				str = "╗";
			else if (i == 18 && j == 18)
				str = "╝";
			else if (i == 0)
				str = "╠";
			else if (i == 18)
				str = "╣";
			else if (j == 0)
				str = "╦";
			else if (j == 18)
				str = "╩";
			else str = "╬";
			PrintInXY(i * 2 + Left, j + Top, str);
		}
	}
	//═║╔╗╚╝╠╣╦╩╬○●
}
void Game() {
	int Winner;
	bool isBlack = true;
	ShowInfo(isBlack);
	int x = 0, y = 0;
	do {
		if (isBlack) {
			COORD pos = getMouseXY(LEFT_CLICK);
			x = (pos.X - Left) / 2, y = pos.Y - Top;
			if (x > 18 || x < 0 || y > 18 || y < 0)
				continue;
			if (ChessBoard[x][y] == 0) {
				PrintInXY(x * 2 + Left, y + Top, BlackChess);
				ChessBoard[x][y] = BLACK;
				isBlack = !isBlack;
				ShowInfo(isBlack);
			}
		}
		else {
			COORD pos = getMouseXY(RIGHT_CLICK);
			x = (pos.X - Left) / 2, y = pos.Y - Top;
			if (x > 18 || x < 0 || y > 18 || y < 0)
				continue;
			if (ChessBoard[x][y] == 0) {
				PrintInXY(x * 2 + Left, y + Top, WhiteChess);
				ChessBoard[x][y] = WHITE;
				isBlack = !isBlack;
				ShowInfo(isBlack);
			}
		}
		Winner = CheckWin(x, y);
		if (Winner)break;
	} while (true);
	Message(Winner);
}
GameState CheckWin(int x, int y) {
	int tmp = ChessBoard[x][y];
	int num[4] = { 1,1,1,1 };
	int i, j, m, n;
	for (i = 0; i < 8; i++) {
		m = x; n = y; j = i % 4;
		m += Direct[i][0];
		n += Direct[i][1];
		while (ChessBoard[m][n] == tmp) {
			m += Direct[i][0];
			n += Direct[i][1];
			num[j]++;
		}
	}
	for (i = 0; i < 4; i++)
		if (num[i] >= 5)
			return tmp;
	return PLAYING;
}
void Message(int whoWin) {
	char * WhoWin;
	int x = 7 * 2 + Left, y = 9 + Top;
	char * str;
	str = "╔═════════╗";
	PrintInXY(x - 6, y - 1, str);
	str = "║                  ║";
	PrintInXY(x - 6, y, str);
	str = "╚═════════╝";
	PrintInXY(x - 6, y + 1, str);
	if (whoWin == BLACKWIN) {
		WhoWin = "黑棋赢了";
		PrintInXY(x, y, WhoWin);
	}
	else {
		WhoWin = "白棋赢了";
		PrintInXY(x, y, WhoWin);
	}
}

迷宫(随机生成)

#include<iostream>
#include<cstdlib>
#include<conio.h>
#include<ctime>
#include<Windows.h>
using namespace std;
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define TOP 1
#define LEFT (2 * TOP)
#define MAX_SIZE 40
#define RANDOM(min, max) ((min) + (rand()%((max) - (min) + 1)))
#define ROAD 0
#define WALL 1
#define END 2
typedef struct PlayerCharacter {
	int x, y;
	char *PC;
	PlayerCharacter() {
		PC = "●";
		x = y = 1;
	}
}PlayerCharacter;
typedef struct RandomMap {
	int **Map;
	int mapW, mapH;
	long mapID;
	RandomMap() {
		mapW = 2 * RANDOM(8, MAX_SIZE / 2) + 1;
		mapH = 2 * RANDOM(5, MAX_SIZE / 2) + 1;
		Map = (int**)malloc(mapH * sizeof(int*));
		for (int i = 0; i < mapH; i++) {
			Map[i] = (int*)malloc(mapW * sizeof(int));
			for (int j = 0; j < mapW; j++)
				Map[i][j] = WALL;
		}
	}
}RandomMap;
void GotoXY(short x, short y);//光标移动
void HideCursor();
void Create(RandomMap rMap, int m, int n);
void InitMap(RandomMap rMap);
void PaintMapPoint(RandomMap rMap, int x, int y);
void GamePlaying(PlayerCharacter &pc);
void PaintPC(PlayerCharacter pc);
void Move(RandomMap rMap, PlayerCharacter &pc, int x, int y);

int main() {
	SYSTEMTIME sys[2];
	system("MODE con: COLS=120 LINES=50");
	srand((unsigned int)time(0));
	HideCursor();
	PlayerCharacter pc;
	GetLocalTime(&sys[0]);
	GamePlaying(pc);
	GetLocalTime(&sys[1]);
	int mm = sys[1].wMinute - sys[0].wMinute, ss = sys[1].wSecond - sys[0].wSecond;
	if (ss < 0) {
		ss += 60;
		mm -= 1;
	}
	else if (ss > 59) {
		ss -= 60;
		mm += 1;
	}
	printf("\n好牛逼啊,走出迷宫只花了%2d:%2d的时间!\n", mm, ss);
	return 0;
}

void GotoXY(short x, short y) {
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { x,y });
}
void HideCursor() {
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
bool CheckBorder(RandomMap rMap, int x, int y) {
	if (x <= 0 || y <= 0 || x >= rMap.mapW - 1 || y >= rMap.mapH - 1)return true;
	else return false;
}
bool CheckOutside(RandomMap rMap, int x, int y) {
	if (x < 0 || y < 0 || x > rMap.mapW - 1 || y > rMap.mapH - 1)return false;
	else return true;
}
void Create(RandomMap rMap, int m, int n) {
	int next[4][2] = {
		{ 0,1 },
		{ 1,0 },
		{ 0,-1 },
		{ -1,0 }
	};
	int i, j, t;
	for (i = 0; i<4; i++) {
		j = rand() % 4;
		t = next[i][0], next[i][0] = next[j][0], next[j][0] = t;
		t = next[i][1], next[i][1] = next[j][1], next[j][1] = t;
	}
	rMap.Map[m][n] = ROAD;
	for (i = 0; i<4; i++)
		if (!CheckBorder(rMap, n + 2 * next[i][1], m + 2 * next[i][0]) && rMap.Map[m + 2 * next[i][0]][n + 2 * next[i][1]] == WALL) {
			rMap.Map[m + next[i][0]][n + next[i][1]] = ROAD;
			Create(rMap, m + 2 * next[i][0], n + 2 * next[i][1]);
		}
}
void InitMap(RandomMap rMap) {
	Create(rMap, 1, 1);
	rMap.Map[rMap.mapH - 2][rMap.mapW - 2] = END;
	for (int i = 0; i < rMap.mapW; i++) {
		for (int j = 0; j < rMap.mapH; j++) {
			PaintMapPoint(rMap, i, j);
		}
	}
}
void PaintMapPoint(RandomMap rMap, int x, int y) {
	GotoXY(x * 2 + LEFT, y + TOP);
	switch (rMap.Map[y][x]) {
	case 0:
		printf("  ");
		break;
	case 1:
		printf("※");
		break;
	case 2:
		printf(" E");
		break;
	}
}
void PaintPC(PlayerCharacter pc) {
	GotoXY(pc.x * 2 + LEFT, pc.y + TOP);
	printf("%s", pc.PC);
}
void Move(RandomMap rMap, PlayerCharacter &pc, int x, int y) {
	PaintMapPoint(rMap, pc.x, pc.y);
	pc.x += x;
	pc.y += y;
	PaintPC(pc);
}
void GamePlaying(PlayerCharacter &pc) {
	RandomMap rm;
	InitMap(rm);
	PaintPC(pc);
	int x, y;
	while (pc.x != rm.mapW - 2 || pc.y != rm.mapH - 2) {
		x = 0;
		y = 0;
		if (KEYDOWN(VK_UP)) {
			y--;
		}
		if (KEYDOWN(VK_DOWN)) {
			y++;
		}
		if (KEYDOWN(VK_LEFT)) {
			x--;
		}
		if (KEYDOWN(VK_RIGHT)) {
			x++;
		}
		if (x || y)
			if (CheckOutside(rm, pc.x + x, pc.y + y) && rm.Map[pc.y + y][pc.x + x] != WALL) {
				Move(rm, pc, x, y);
			}
		Sleep(100);
	}
	GotoXY(LEFT, rm.mapH + TOP);
}

贪吃蛇

 #include <Windows.h>
 #include <iostream>
 #include <ctime>
 #include <conio.h>
 #include <cstdlib>
 using namespace std;

 #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
 #define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
 #define RANDOM(min, max) ((min) + (rand()%((max) - (min) + 1)))
 #define MAP_SIZE 20
 #define TOP 1
 #define LEFT (TOP * 2)
 #define WIN 1
 #define LOSE -1
 #define GAMING 0
 //-------------贪吃蛇自身结构---------
 typedef struct Position {
 	int x;
 	int y;
 	Position operator+(Position op) {
 		return{ x + op.x,y + op.y };
 	}
 	Position operator-(Position op) {
 		return{ x - op.x,y - op.y };
 	}
 	bool operator!=(Position op) {
 		return (x != op.x || y != op.y);
 	}
 	Position(int i = 0, int j = 0) {
 		x = i; y = j;
 	}
 }Position, Direction;
 typedef struct SnakeNode {
 	SnakeNode* next;
 	SnakeNode* prev;
 	Position pos;
 	Direction dir;
 }*SnakeBody;
 typedef struct Snake {
 	SnakeBody head, tail;
 	int length;
 	Snake() {
 		length = 8;
 		head = new SnakeNode();
 		SnakeBody q = head;
 		for (int i = 0; i < length; i++) {
 			SnakeBody p = new SnakeNode();
 			p->pos = { 0 , length - i - 1 };
 			p->dir.x = 0;
 			p->dir.y = 1;
 			p->prev = NULL;
 			if (i == 0) {
 				q = head = p;
 			}
 			else {
 				p->prev = q;
 				q->next = p;
 				q = q->next;
 			}
 		}
 		tail = q;
 		tail->next = NULL;
 	}
 }Snake;
 int Map[MAP_SIZE][MAP_SIZE];

 //----------相关函数--------
 void GotoXY(short x, short y);//光标移动
 void HideCursor();//隐藏光标
 void Gaming();

 int main() {
 	system("MODE con: COLS=50 LINES=22");
 	srand((unsigned int)time(0));
 	HideCursor();
 	Gaming();
 	return 0;
 }

 void GotoXY(short x, short y) {
 	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), { x,y });
 }
 void HideCursor() {
 	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
 	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
 }
 void MoveSnake(Snake &S) {
 	SnakeBody p = S.head;
 	while (p) {
 		if (!p->next)
 			Map[p->pos.y][p->pos.x] = 0;
 		if (p == S.head)
 			Map[p->pos.y][p->pos.x] = 1;
 		p->pos = p->pos + p->dir;
 		p = p->next;
 	}
 	Map[S.head->pos.y][S.head->pos.x] = 2;

 }
 void PaintSnake(Snake &S) {
 	SnakeBody p = S.head;
 	Position q;
 	while (p) {
 		q = p->pos - p->dir;
 		GotoXY(2 * q.x + LEFT, q.y + TOP);
 		printf("  ");
 		p = p->next;
 	}
 	p = S.head;
 	while (p) {
 		q = p->pos;
 		GotoXY(2 * q.x + LEFT, q.y + TOP);
 		printf("□");
 		p = p->next;
 	}
 	GotoXY(2 * S.head->pos.x + LEFT, S.head->pos.y + TOP);
 	printf("○");
 }
 void CreateFood() {
 	int x, y;
 	do {
 		x = RANDOM(1, MAP_SIZE - 1);
 		y = RANDOM(1, MAP_SIZE - 1);
 	} while (Map[y][x] != 0);
 	Map[y][x] = 3;
 	GotoXY(LEFT + 2 * x, TOP + y);
 	printf("★");
 }
 void Gaming() {
 	for (int i = -1; i <= MAP_SIZE; i++) {
 		GotoXY(LEFT + 2 * i, 0);
 		printf("※");
 		GotoXY(LEFT + 2 * i, TOP + MAP_SIZE);
 		printf("※");
 	}
 	for (int i = -1; i <= MAP_SIZE; i++) {
 		GotoXY(0, TOP + i);
 		printf("※");
 		GotoXY(LEFT + 2 * MAP_SIZE, TOP + i);
 		printf("※");
 	}
 	Snake snake;
 	Direction nowD = { 0,1 };
 	for (int i = 0; i < MAP_SIZE; i++)
 		for (int j = 0; j < MAP_SIZE; j++)
 			Map[i][j] = 0;
 	SnakeBody p = snake.head;
 	while (p) {
 		GotoXY(LEFT + 2 * p->pos.x, TOP + p->pos.y);
 		if(p == snake.head)
 			printf("○");
 		else
 			printf("□");
 		p = p->next;
 	}
 	p = snake.head;
 	while (p) {
 		if(p == snake.head)Map[p->pos.y][p->pos.x] = 2;
 		else Map[p->pos.y][p->pos.x] = 1;
 		p = p->next;
 	}
 	CreateFood();
 	bool win = false;
 	while (true) {
 		if (_kbhit()) {
 			if (KEYDOWN(VK_UP)) {
 				if (nowD != Direction(0,1))
 					nowD = { 0,-1 };
 			}
 			if (KEYDOWN(VK_DOWN)) {
 				if (nowD != Direction(0, -1))
 					nowD = { 0,1 };
 			}
 			if (KEYDOWN(VK_LEFT)) {
 				if (nowD != Direction(1, 0))
 					nowD = { -1,0 };
 			}
 			if (KEYDOWN(VK_RIGHT)) {
 				if (nowD != Direction(-1, 0))
 					nowD = { 1,0 };
 			}
 		}
 		snake.head->dir = nowD;
 		for (SnakeBody p = snake.head->next;p; p = p->next) {
 			p->dir = p->prev->pos - p->pos;
 		}
 		if (Map[snake.head->pos.y + snake.head->dir.y][snake.head->pos.x + snake.head->dir.x] == 1) {
 			break;
 		}
 		if (Map[snake.head->pos.y + snake.head->dir.y][snake.head->pos.x + snake.head->dir.x] == 3) {
 			SnakeBody q = new SnakeNode();
 			q->dir = snake.tail->dir;
 			q->pos = snake.tail->pos - snake.tail->dir;
 			q->next = NULL;
 			q->prev = snake.tail;
 			snake.tail->next = q;
 			snake.tail = q;
 			snake.length++;
 			Map[q->pos.y][q->pos.x] = 1;
 			CreateFood();
 		}
 		if (Map[snake.head->pos.y][snake.head->pos.x] == 1) {
 			break;
 		}
 		MoveSnake(snake);
 		PaintSnake(snake);
 		if (snake.length == MAP_SIZE * MAP_SIZE - 1) {
 			win = true;
 			break;
 		}
 		if (snake.head->pos.x < 0 || snake.head->pos.x >= MAP_SIZE || snake.head->pos.y < 0 || snake.head->pos.y >= MAP_SIZE) {
 			break;
 		}
 		Sleep(200);
 	}
 }