ゲームプログラミング:C++で15パズルを作ってみた
概要
はい、前回に引き続きコンソールゲームプログラミングですね。
今回はもっと簡単です。
https://qiita.com/Chomolungma/items/52bd8b133b747cb603e7
以下を参考にしながら15パズルを作成しました。
館長、ありがとう!!!
https://www.youtube.com/watch?v=YoQt9RHy8rA
とりあえずうまく動作していそうです。
まず15パズルで遊んだことが無かったので、このゲームの操作法やら攻略法に苦戦しました。
ゲームプレーヤーとして未熟なのに開発側に回りました、ホントすみません。
所感
思ったんですが、トップダウンに(設計→実装)とした方が、やっぱりキレイなコード書ける気がします。
ボトムアップだとちょこちょこ動かしながら楽しめるのですが、main関数にある長ったらしい処理を抽出して、関数化するというのが面倒に感じます(笑)
「もう動くからいいじゃん!」みたいな・・・
自分がウォーターフォールしか経験したこと無かったので、こういうのは新鮮でした。
16マスの範囲外へアクセスすることに対する防御的プログラミングといったことは、すぐに頭に浮かんできますが、そういう石橋を叩いて渡るスタイルだと、動くところまで辿り着きにくいのかもなぁと、ちょっと考え直しました。
コード
せっかくなので、コードを公開します。
ご自由にお試し下さい。
ホントはコメントとかネーミングとかもうちょっと考えて、初学者の方が分かるようにしたいと思っていますが・・・
C++的に記述できていないところも多い(構造体使うならクラス使えよ!)ので、ちょこちょこ修正していこうと思います。
回帰テストせなアカンで!!!
※コードレビューコメント頂けますと幸いです
#include <iostream>
#include <iomanip>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
static const int BOARD_WIDTH = 4;
static const int BOARD_HEIGHT = 4;
static const int BLANK_NUMBER = 16;
int board[BOARD_HEIGHT][BOARD_WIDTH];
struct Vec2
{
int x;
int y;
};
Vec2 getBlankPosition();
void moveBlank(Vec2 argMovePosition);
int main()
{
for (int y = 0; y < BOARD_HEIGHT; ++y)
{
for (int x = 0; x < BOARD_WIDTH; ++x)
{
board[y][x] = y * BOARD_HEIGHT + x + 1;
}
}
srand(static_cast<int>(time(NULL)));
for (int i = 0; i < 1000; ++i)
{
Vec2 blankPosition = getBlankPosition();
Vec2 movePosition = blankPosition;
switch (rand() % BOARD_HEIGHT)
{
case 0:
++(movePosition.y);
break;
case 1:
--(movePosition.y);
break;
case 2:
++(movePosition.x);
break;
case 3:
--(movePosition.x);
break;
}
moveBlank(movePosition);
}
while (1)
{
system("cls");
std::cout << "+--+--+--+--+" << std::endl;
for (int y = 0; y < BOARD_HEIGHT; ++y)
{
for (int x = 0; x < BOARD_WIDTH; ++x)
{
if (BLANK_NUMBER == board[y][x])
{
std::cout << "| ";
}
else
{
std::cout << "|" << std::setw(2) << board[y][x];
}
}
std::cout << "|" << std::endl;
std::cout << "+--+--+--+--+" << std::endl;
}
bool isClear = true;
for (int y = 0; y < BOARD_HEIGHT; ++y)
{
for (int x = 0; x < BOARD_WIDTH; ++x)
{
if (board[y][x] != y * BOARD_HEIGHT + x + 1)
{
isClear = false;
}
}
}
if (true == isClear)
{
std::cout << "Clear!" << std::endl;
}
Vec2 blankPosition = getBlankPosition();
Vec2 movePosition = blankPosition;
switch (_getch())
{
case 'w':
++(movePosition.y);
break;
case 's':
--(movePosition.y);
break;
case 'a':
++(movePosition.x);
break;
case 'd':
--(movePosition.x);
break;
}
moveBlank(movePosition);
}
_getch();
return 0;
}
Vec2 getBlankPosition()
{
Vec2 blankPosition = { -1, -1 };
for (int y = 0; y < BOARD_HEIGHT; ++y)
{
for (int x = 0; x < BOARD_WIDTH; ++x)
{
if (BLANK_NUMBER == board[y][x])
{
blankPosition = { x ,y };
}
}
}
return blankPosition;
}
void moveBlank(Vec2 argMovePosition)
{
if (argMovePosition.x < 0 || argMovePosition.x >= BOARD_WIDTH || argMovePosition.y < 0 || argMovePosition.y >= BOARD_HEIGHT)
{
return;
}
Vec2 blankPosition = getBlankPosition();
// swapping
int tempBlank = board[blankPosition.y][blankPosition.x];
board[blankPosition.y][blankPosition.x] = board[argMovePosition.y][argMovePosition.x];
board[argMovePosition.y][argMovePosition.x] = tempBlank;
}
Author And Source
この問題について(ゲームプログラミング:C++で15パズルを作ってみた), 我々は、より多くの情報をここで見つけました https://qiita.com/Chomolungma/items/6cf6a76ebfb6201ea7fa著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .