画像(logo)

HOME/[C言語]サンプルプログラム集 目次/数字並べ替えゲーム

広告

[C言語 サンプルプログラム集]
数字並べ替えゲーム

広告

↓2016年02月29日発売↓

12歳からはじめる ゼロからのC言語 ゲームプログラミング教室

目次へ戻る

数字並べ替えゲーム

今回は数字を並べ替えるゲームを作ります。

画像(cs_10_1)

1〜8までの数字キーで空いてるマスに数字を移動させて

123
456
78

の並びにするゲームになります。

ヘッダファイル

今回必要なヘッダファイルです。

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>

<stdio.h>以外を説明します。

<stdlib.h>

乱数を発生させる「srand()」、「rand()」、画面を消去する「system("cls")」などで使います。

<conio.h>

キー入力の「_getch()」などで使います。

<time.h>

時間を調べる「time()」で使います。今回は乱数の命令と一緒に使ってます。

ヘッダファイルの意味についてはわからなそうな用語集のヘッダファイルを見てください。

変数

int key;
int count;
int count2;
int rnd1,rnd2;
int w = 0;
int ary_x = 0;
int ary_y = 0;
int i,j;
int index = 0;
int success_flag = 0;
int break_flag = 1;

int number[9] = {1,2,3,4,5,6,7,8,9};

int numbers[5][5] = {
	{0,0,0,0,0},
	{0,1,2,3,0},
	{0,4,5,6,0},
	{0,7,8,9,0},
	{0,0,0,0,0}
};

大事な役割を持つ変数が

/*入力されたキーを保存*/
int key = 0;
/*配列を入れ替える時に一時的に値を保存する変数*/
int w = 0;
/*入力された数字の配列におけるx座標を保存*/
int ary_x = 0;
/*入力された数字の配列におけるy座標を保存*/
int ary_y = 0;

この4つと、

int numbers[5][5] = {
	{0,0,0,0,0},
	{0,1,2,3,0},
	{0,4,5,6,0},
	{0,7,8,9,0},
	{0,0,0,0,0}
};

ゲームの土台となる2次元配列になります。

この2次元配列がなぜ「3×3」ではなく「5×5」になっているかというのは、数字を動かす時に必要になるので後ほど説明いたします。

その他はゲームのループ用や問題の数字を最初に並べ替える為の乱数用変数などになります。

問題となる2次元配列を並べ替える

まずは2次元配列を並べ替えます。

int numbers[5][5] = {
	{0,0,0,0,0},
	{0,1,2,3,0},
	{0,4,5,6,0},
	{0,7,8,9,0},
	{0,0,0,0,0}
};

こちらですね。

この中の回りを囲っている「0」に触れずに中身の「1〜9」だけをランダムに入れ替えます。

先に乱数の使い方ですが、

srand((unsigned)time(NULL));
rnd1 = rand() % 100;

まず一行目「srand()」というのは、乱数を使う時に初期値を設定するという関数になります。

初期値?と思われるかもしれませんが、これ以上の詳しい説明はゲームテクニック集の乱数をご覧ください。

そして2行目の後ろの「100」この数字を変える事によって必要な範囲の乱数を発生させる事ができます。

ここを「10」にすると「0〜9」まで、「50」にすると「0〜49」までという具合に乱数の範囲を決める事ができます。

ではソースをあらためてみてみると

srand((unsigned)time(NULL));
for (count = 0; count < 10; count++){
	rnd1 = rand() % 3 + 1;
	rnd2 = rand() % 3 + 1;
	w = numbers[1][1];
	numbers[1][1] = numbers[rnd1][rnd2];
	numbers[rnd1][rnd2] = w;
}

「for」ループの中に注目です。

rnd1 = rand() % 3 + 1;
rnd2 = rand() % 3 + 1;

このようになっておりますね。

「rand() % 3」なので発生する乱数は「0,1,2」そこに「+1」するので「1,2,3」の値がランダムに得られます。

なのでこの値を使って並べ替えをすれば回りを囲っている「0」には触れずに並べ替えられるというワケです。

数字を入れ替えるアルゴリズムについてはサンプルプログラム集 入れ替えにて紹介しておりますのでよろしければご覧ください。

2次元配列を表示

次に2次元配列を表示します。

for(i=0;i<5;i++){
	for(j=0;j<5;j++){
		if(numbers[i][j] == 0)printf("■");
	}
	printf("\n");
}

2次元配列をいじる時は2重の「for」ループが便利です。

慣れないとわかりづらいとは思いますが簡単なイメージとしては、まず内側の「for」ループによって2次元配列の横一列を調べて、そしてそれが終わったら外側の「for」ループを一つ進めるみたいなイメージになります。

そしてそれぞれ中身の要素を調べて置き換えて表示します。

if(numbers[i][j] == 0)printf("■");

内側のループ終わりに「printf("\n");」と改行するとこにも注意です。

今回のソースでは超初心者向けという事でこの表示部分をゲーム開始時に一か所、ゲーム進行時に一か所と計二か所同じ処理を書いておりますがもちろん関数にまとめて書いても大丈夫です。

キー入力

次にキー入力の処理をやっていきます。

キー入力や先ほど紹介した乱数などはよくでてくるのでカタチで覚えましょう。

key = _getch();
if(key == 0 || key == 224)key = _getch();

「_getch()」こちらは一文字だけキー入力を受け付ける関数になります。

入力待ちになる事とキーが押された瞬間(Enterキーを押さなくても)に入力を受け取るトコロに注意です。

そして受け取ったキーコードを変数「key」に保存します。

その次の「if(key == 0 || key == 224)」これは矢印など一部の特別なキーは入力をなぜか2回受け取るので、その余分な一回を受け流す処理になります。

もう少し詳しく知りたい方はこちらもゲームテクニック集の矢印キーリアルタイム入力をご覧ください。

1〜9の文字コード

それではようやく下準備的な部分ができたのでゲームの処理部分を作っていきます。

まずは文字コードについてみてみましょう。

#include <stdio.h>

int main(){
	printf("1 = %d\n",'1');
	printf("2 = %d\n",'2');
	printf("3 = %d\n",'3');

	return 0;
}

■実行結果■

画像(cs_10_2)

1・2・3の文字コードを表示するプログラムです。

後ろの数字を「'a'」にすれば「a」の文字コードが調べられます。

結果は見たままですが

「1」→「49」

「2」→「50」

「3」→「51」

となります。

つまりは数字の「1〜9」は文字コードでいうトコロの「49〜57」になります。

では「1〜9」の文字コードがわかった所でソースを見てみましょう。

if((key >= 49 && key <= 56) || key == 122){
	break_flag = 0;
	if(key == 122){
		count2 = 50;
	}
}
else{
	printf("無効なキーです!\n");
}

前半の部分に注目です。

if((key >= 49 && key <= 56)

文字コードが49以上56以内ならって事ですね。

数字に直すと1以上8以下になりますね。

これで入力されたキーが「1〜8」以外だったら入力をやり直させる事ができるというワケです。

あとその後ろの「key == 122」は終了条件の「z」を押された時のキーコードです。

押された場所を調べる

キー入力された数字が2次元配列のどの位置にあるかを調べます。

for(i=0;i<5;i++){
	for(j=0;j<5;j++){
		if(numbers[i][j] == key - 48){
			ary_y = i;
			ary_x = j;
		}
	}
}

2次元配列を調べる時は2重の「for」ループでしたね。

2次元配列の中の数字は文字コードではなく普通の数字なので先ほどのキーコードを「key - 48」と「48」引いてあげる事によって普通の数字に戻す事ができます。

そして目当ての数字が見つかった時点で場所を変数「ary_y,ary_x」に保存します。

並べ替え

では変数「ary_y,ary_x」に保存された位置情報を使って並べ替えをします。

if(numbers[ary_y + 1][ary_x] == 9){
	w = numbers[ary_y + 1][ary_x];
	numbers[ary_y + 1][ary_x] = numbers[ary_y][ary_x];
	numbers[ary_y][ary_x] = w;
}

調べる場所は上下左右の四か所ですね。

調べる条件は2次元配列の要素「9」が空白の役わりをしているので調べた位置が「9」だったらそこと入れ替えて場所を移動します。

if(numbers[ary_y + 1][ary_x] == 9)

こちらが「ary_y + 1」と一つ上の場所を調べている場合ですね。

この調べる時に配列をはみ出して調べたりしてしまういわゆる「バッファオーバーフロー」を避けるために2次元配列を一回り大きく「5×5」にしたというワケです。

同じように他の場所も調べてあげます。

完成

あとは正解判定などを入れてゲーム全体のカタチを整えれば完成です。

ソースになります。

数字並べ替えゲームソース

□ページの先頭へ□

□目次へ戻る□

□HOME□

広告

↓2017年06月16日発売↓

やさしいC 第5版 (「やさしい」シリーズ)

新品価格
¥2,700から
(2017/5/1 13:05時点)

↓2014年08月09日発売↓

新・明解C言語 入門編 (明解シリーズ)

新品価格
¥2,484から
(2017/5/1 13:08時点)

↓2016年02月20日発売↓

新・解きながら学ぶC言語

新品価格
¥2,160から
(2017/5/1 13:10時点)

↓2017年02月11日発売↓

C言語プログラミング基本例題88 88

新品価格
¥3,024から
(2017/5/1 13:12時点)

↓2016年12月15日発売↓

Cの絵本 第2版 C言語が好きになる新しい9つの扉

新品価格
¥1,490から
(2017/5/1 13:13時点)

↓2017年02月08日発売↓

新・明解C言語で学ぶアルゴリズムとデータ構造 (明解シリーズ)

新品価格
¥2,700から
(2017/5/1 13:15時点)