게임 프로그래밍 : C++에서 마인 스위퍼를 만들어 보았습니다.
개요
콘솔 게임 프로그래밍은 다섯 번째!
2D로 필드가 깨끗하게 준비되는 타입의 게임은 이미 만드는 방법을 알고 있네요.
이번에는 마인 스위퍼입니다.
이곳은 옛날 해본 적이 있었다고 생각했습니다만, 당시는 「지뢰를 폭파시키면 이길」이라고 생각하고 있었습니다.
「얼마나 빨리 지뢰를 폭파할 것인가」경쟁하는 게임이라고 해석하고 있어, 어쩐지 재미없다고 생각하고 있었습니다.
그래? 여러분도 그렇습니까?
아니-, 추론을 구사해 즐기는 게임이었다고는···좋네요, 재미있다! !
다음을 참고하면서 마인 스위퍼를 만들었습니다.
나 개인이 고려한 사양으로, 플래그를 세운 개소의 광석을 없앨 수 없게 했습니다.
관장, 감사합니다! ! !
htps: //같다. 베 / CHd 코 b-8 오 Q
우선 잘 동작하고 있다고 합니다.
오, 여기는 분명히 지뢰!
그럼 여기에 플래그를 세우면 ...
낙승 낙승~
그래 아 아 아 아 아 아 아! !
코드
모처럼이므로 코드를 게시합니다.
자유롭게 시험해 주세요.
정말은 코멘트라든지 네이밍이라도 조금 생각해, 초학자쪽을 알도록(듯이) 하고 싶습니다만・・・
변함없이 부적절한 코딩이 있기 때문에, 잠깐 수정해 가려고 생각합니다.
회귀 테스트하지 않는 아칸으로! ! !
※코드 리뷰 코멘트 받을 수 있으면 다행입니다
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
static const int FIELD_WIDTH = 9;
static const int FIELD_HEIGHT = 9;
static const int BOMB_COUNT = 10;
int cursorX;
int cursorY;
struct Cell
{
bool isExistBomb;
bool isHiddenByMine;
bool isOnFlag;
};
Cell cells[FIELD_WIDTH][FIELD_HEIGHT];
int getAdjacentBombsCount(int x, int y);
void autoRemoveMines(int argX, int argY);
int main()
{
// initialize.
srand(static_cast<unsigned int>(time(NULL)));
{
int count = 0;
while(count < BOMB_COUNT)
{
int x = rand() % FIELD_WIDTH;
int y = rand() % FIELD_HEIGHT;
if (false == cells[x][y].isExistBomb)
{
cells[x][y].isExistBomb = true;
++count;
}
}
}
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
cells[x][y].isHiddenByMine = true;
}
}
bool isExplosion = false;
bool isClear = false;
while (1)
{
system("cls");
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
if ((cursorX == x) && (cursorY == y))
{
if (true == isExplosion)
{
std::cout << "※";
}
else
{
std::cout << "◎";
}
}
else if (true == cells[x][y].isOnFlag)
{
std::cout << "▲";
}
else if (true == cells[x][y].isHiddenByMine)
{
std::cout << "■";
}
else if (true == cells[x][y].isExistBomb)
{
std::cout << "●";
}
else
{
int AdjacentBombs = getAdjacentBombsCount(x, y);
if (AdjacentBombs > 0)
{
char str[] = "0";
str[1] += AdjacentBombs;
std::cout << str;
}
else
{
std::cout << "・";
}
}
}
std::cout << std::endl;
}
// Game Over.
if (true == isExplosion)
{
std::cout << "Game Over...";
std::cout << "\a";
_getch();
break;
}
// Game Clear.
if (true == isClear)
{
std::cout << "Game Clear!";
std::cout << "\a";
_getch();
break;
}
switch (_getch())
{
case 'w':
--cursorY;
break;
case 's':
++cursorY;
break;
case 'a':
--cursorX;
break;
case 'd':
++cursorX;
break;
/* DEBUG
case 'b':
cells[cursorX][cursorY].isExistBomb = !cells[cursorX][cursorY].isExistBomb;
break;
case 'm':
cells[cursorX][cursorY].isHiddenByMine = !cells[cursorX][cursorY].isHiddenByMine;
break;
*/
case 'f':
cells[cursorX][cursorY].isOnFlag = !cells[cursorX][cursorY].isOnFlag;
break;
default:
// disable to remove mine.
if (true == cells[cursorX][cursorY].isOnFlag)
{
break;
}
cells[cursorX][cursorY].isHiddenByMine = false;
// Judge Game Over.
if (true == cells[cursorX][cursorY].isExistBomb)
{
isExplosion = true;
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
cells[x][y].isHiddenByMine = false;
cells[x][y].isOnFlag = false;
}
}
break;
}
// Judge Game Clear.
{
isClear = true;
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
if ((false == cells[x][y].isExistBomb) && (true == cells[x][y].isHiddenByMine))
{
isClear = false;
}
}
}
}
// Remove Adjacent Mines Automatically.
for (int y = -1; y <= 1; ++y)
{
for (int x = -1; x <= 1; ++x)
{
if ((0 == x) && (0 == y))
{
continue;
}
autoRemoveMines(cursorX + x, cursorY + y);
}
}
break;
}
}
return 0;
}
int getAdjacentBombsCount(int argX, int argY)
{
int count = 0;
for (int y = -1; y <= 1; ++y)
{
for (int x = -1; x <= 1; ++x)
{
if ((0 == x) && (0 == y))
{
continue;
}
if ((argX + x < 0) || (argX + x >= FIELD_WIDTH) || (argY + y < 0) || (argY + y >= FIELD_HEIGHT))
{
continue;
}
if (true == cells[argX + x][argY + y].isExistBomb)
{
++count;
}
}
}
return count;
}
void autoRemoveMines(int argX, int argY)
{
if ((true == cells[argX][argY].isExistBomb)
|| (false == cells[argX][argY].isHiddenByMine)
|| (argX < 0) || (argX >= FIELD_WIDTH) || (argY < 0) || (argY >= FIELD_HEIGHT)
|| (getAdjacentBombsCount(argX, argY) > 0))
{
return;
}
cells[argX][argY].isHiddenByMine = false;
for (int y = -1; y <= 1; ++y)
{
for (int x = -1; x <= 1; ++x)
{
if ((0 == x) && (0 == y))
{
continue;
}
autoRemoveMines(argX + x, argY + y);
}
}
}
Reference
이 문제에 관하여(게임 프로그래밍 : C++에서 마인 스위퍼를 만들어 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Chomolungma/items/1bc698928d0e7b38b173
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
모처럼이므로 코드를 게시합니다.
자유롭게 시험해 주세요.
정말은 코멘트라든지 네이밍이라도 조금 생각해, 초학자쪽을 알도록(듯이) 하고 싶습니다만・・・
변함없이 부적절한 코딩이 있기 때문에, 잠깐 수정해 가려고 생각합니다.
회귀 테스트하지 않는 아칸으로! ! !
※코드 리뷰 코멘트 받을 수 있으면 다행입니다
#include <iostream>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
static const int FIELD_WIDTH = 9;
static const int FIELD_HEIGHT = 9;
static const int BOMB_COUNT = 10;
int cursorX;
int cursorY;
struct Cell
{
bool isExistBomb;
bool isHiddenByMine;
bool isOnFlag;
};
Cell cells[FIELD_WIDTH][FIELD_HEIGHT];
int getAdjacentBombsCount(int x, int y);
void autoRemoveMines(int argX, int argY);
int main()
{
// initialize.
srand(static_cast<unsigned int>(time(NULL)));
{
int count = 0;
while(count < BOMB_COUNT)
{
int x = rand() % FIELD_WIDTH;
int y = rand() % FIELD_HEIGHT;
if (false == cells[x][y].isExistBomb)
{
cells[x][y].isExistBomb = true;
++count;
}
}
}
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
cells[x][y].isHiddenByMine = true;
}
}
bool isExplosion = false;
bool isClear = false;
while (1)
{
system("cls");
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
if ((cursorX == x) && (cursorY == y))
{
if (true == isExplosion)
{
std::cout << "※";
}
else
{
std::cout << "◎";
}
}
else if (true == cells[x][y].isOnFlag)
{
std::cout << "▲";
}
else if (true == cells[x][y].isHiddenByMine)
{
std::cout << "■";
}
else if (true == cells[x][y].isExistBomb)
{
std::cout << "●";
}
else
{
int AdjacentBombs = getAdjacentBombsCount(x, y);
if (AdjacentBombs > 0)
{
char str[] = "0";
str[1] += AdjacentBombs;
std::cout << str;
}
else
{
std::cout << "・";
}
}
}
std::cout << std::endl;
}
// Game Over.
if (true == isExplosion)
{
std::cout << "Game Over...";
std::cout << "\a";
_getch();
break;
}
// Game Clear.
if (true == isClear)
{
std::cout << "Game Clear!";
std::cout << "\a";
_getch();
break;
}
switch (_getch())
{
case 'w':
--cursorY;
break;
case 's':
++cursorY;
break;
case 'a':
--cursorX;
break;
case 'd':
++cursorX;
break;
/* DEBUG
case 'b':
cells[cursorX][cursorY].isExistBomb = !cells[cursorX][cursorY].isExistBomb;
break;
case 'm':
cells[cursorX][cursorY].isHiddenByMine = !cells[cursorX][cursorY].isHiddenByMine;
break;
*/
case 'f':
cells[cursorX][cursorY].isOnFlag = !cells[cursorX][cursorY].isOnFlag;
break;
default:
// disable to remove mine.
if (true == cells[cursorX][cursorY].isOnFlag)
{
break;
}
cells[cursorX][cursorY].isHiddenByMine = false;
// Judge Game Over.
if (true == cells[cursorX][cursorY].isExistBomb)
{
isExplosion = true;
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
cells[x][y].isHiddenByMine = false;
cells[x][y].isOnFlag = false;
}
}
break;
}
// Judge Game Clear.
{
isClear = true;
for (int y = 0; y < FIELD_HEIGHT; ++y)
{
for (int x = 0; x < FIELD_WIDTH; ++x)
{
if ((false == cells[x][y].isExistBomb) && (true == cells[x][y].isHiddenByMine))
{
isClear = false;
}
}
}
}
// Remove Adjacent Mines Automatically.
for (int y = -1; y <= 1; ++y)
{
for (int x = -1; x <= 1; ++x)
{
if ((0 == x) && (0 == y))
{
continue;
}
autoRemoveMines(cursorX + x, cursorY + y);
}
}
break;
}
}
return 0;
}
int getAdjacentBombsCount(int argX, int argY)
{
int count = 0;
for (int y = -1; y <= 1; ++y)
{
for (int x = -1; x <= 1; ++x)
{
if ((0 == x) && (0 == y))
{
continue;
}
if ((argX + x < 0) || (argX + x >= FIELD_WIDTH) || (argY + y < 0) || (argY + y >= FIELD_HEIGHT))
{
continue;
}
if (true == cells[argX + x][argY + y].isExistBomb)
{
++count;
}
}
}
return count;
}
void autoRemoveMines(int argX, int argY)
{
if ((true == cells[argX][argY].isExistBomb)
|| (false == cells[argX][argY].isHiddenByMine)
|| (argX < 0) || (argX >= FIELD_WIDTH) || (argY < 0) || (argY >= FIELD_HEIGHT)
|| (getAdjacentBombsCount(argX, argY) > 0))
{
return;
}
cells[argX][argY].isHiddenByMine = false;
for (int y = -1; y <= 1; ++y)
{
for (int x = -1; x <= 1; ++x)
{
if ((0 == x) && (0 == y))
{
continue;
}
autoRemoveMines(argX + x, argY + y);
}
}
}
Reference
이 문제에 관하여(게임 프로그래밍 : C++에서 마인 스위퍼를 만들어 보았습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Chomolungma/items/1bc698928d0e7b38b173텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)