0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ゲームプログラミング:C++で15パズルを作ってみた

Posted at

概要

はい、前回に引き続きコンソールゲームプログラミングですね。
今回はもっと簡単です。
 https://qiita.com/Chomolungma/items/52bd8b133b747cb603e7

以下を参考にしながら15パズルを作成しました。
館長、ありがとう!!!
 https://www.youtube.com/watch?v=YoQt9RHy8rA

とりあえずうまく動作していそうです。
まず15パズルで遊んだことが無かったので、このゲームの操作法やら攻略法に苦戦しました。
ゲームプレーヤーとして未熟なのに開発側に回りました、ホントすみません。

スクリーンショット (53).png
16マスにシャッフルされた15個の数字を・・・

スクリーンショット (54).png
揃える!

所感

思ったんですが、トップダウンに(設計→実装)とした方が、やっぱりキレイなコード書ける気がします。
ボトムアップだとちょこちょこ動かしながら楽しめるのですが、main関数にある長ったらしい処理を抽出して、関数化するというのが面倒に感じます(笑)
「もう動くからいいじゃん!」みたいな・・・
自分がウォーターフォールしか経験したこと無かったので、こういうのは新鮮でした。
16マスの範囲外へアクセスすることに対する防御的プログラミングといったことは、すぐに頭に浮かんできますが、そういう石橋を叩いて渡るスタイルだと、動くところまで辿り着きにくいのかもなぁと、ちょっと考え直しました。

コード

せっかくなので、コードを公開します。
ご自由にお試し下さい。
ホントはコメントとかネーミングとかもうちょっと考えて、初学者の方が分かるようにしたいと思っていますが・・・

C++的に記述できていないところも多い(構造体使うならクラス使えよ!)ので、ちょこちょこ修正していこうと思います。
回帰テストせなアカンで!!!

※コードレビューコメント頂けますと幸いです

source.cpp
# 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;
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?