ペントミノ(pentominop)の改良版 [C++]
// pentomino_plus
//
// 2012.03.18 ───── coded by 心如
#include <iostream>
#include <string>
#include <ctime>
using namespace std;
const Bw = 16; // Board-Width
const Bh = 10; // Board-Height
const Sw = 8; // Space-Width
const Sh = 8; // Space-Height
const Sp = Bw + 1; // Start-Point
const Mp = Sh * Bw + Sw;
const Fv = 14; // frame_value
//チップパターンのデータ
struct chip{
int id, s1, s2, s3, s4;
};
struct chip chip_data[] = {
{ 1, 1, 2, 3, 4},
{ 1, 16, 32, 48, 64},
{ 2, 1, 2, 3, 16},
{ 2, 1, 2, 3, 19},
{ 2, 1, 16, 32, 48},
{ 2, 1, 17, 33, 49},
{ 2, 16, 32, 48, 47},
{ 2, 16, 32, 48, 49},
{ 2, 16, 15, 14, 13},
{ 2, 16, 17, 18, 19},
{ 3, 1, 2, 3, 17},
{ 3, 1, 2, 3, 18},
{ 3, 16, 15, 32, 48},
{ 3, 16, 17, 32, 48},
{ 3, 16, 32, 31, 48},
{ 3, 16, 32, 33, 48},
{ 3, 16, 17, 15, 14},
{ 3, 16, 15, 17, 18},
{ 4, 1, 2, 17, 33},
{ 4, 16, 15, 14, 32},
{ 4, 16, 17, 18, 32},
{ 4, 16, 32, 31, 33},
{ 5, 1, 2, 16, 18},
{ 5, 1, 16, 32, 33},
{ 5, 1, 17, 33, 32},
{ 5, 16, 17, 18, 2},
{ 6, 16, 15, 17, 32},
{ 7, 1, 17, 18, 34},
{ 7, 1, 16, 15, 31},
{ 7, 16, 15, 31, 30},
{ 7, 16, 17, 33, 34},
{ 8, 1, 17, 18, 19},
{ 8, 1, 16, 15, 14},
{ 8, 16, 15, 31, 47},
{ 8, 16, 17, 33, 49},
{ 8, 16, 32, 31, 47},
{ 8, 16, 32, 33, 49},
{ 8, 1, 2, 16, 15},
{ 8, 1, 2, 18, 19},
{ 9, 1, 16, 15, 32},
{ 9, 1, 17, 18, 33},
{ 9, 16, 15, 17, 33},
{ 9, 16, 17, 15, 31},
{ 9, 16, 15, 14, 31},
{ 9, 16, 17, 18, 33},
{ 9, 16, 17, 32, 31},
{ 9, 16, 15, 32, 33},
{10, 16, 32, 31, 30},
{10, 1, 2, 16, 32},
{10, 1, 2, 18, 34},
{10, 16, 32, 33, 34},
{11, 1, 16, 32, 31},
{11, 1, 17, 33, 34},
{11, 16, 15, 14, 30},
{11, 16, 17, 18, 34},
{12, 16, 15, 32, 31},
{12, 16, 17, 32, 33},
{12, 1, 16, 17, 32},
{12, 1, 16, 17, 33},
{12, 1, 16, 17, 15},
{12, 1, 16, 17, 18},
{12, 1, 2, 16, 17},
{12, 1, 2, 17, 18},
{13, 0, 1, 16, 17}
};
class Puzzle{
int cnt; // 解のカウンター
int cpm; // チップパターンの数
int board[Bw * Bh]; // ボード
int chip_use[Fv]; // チップの使用フラグ
public:
Puzzle();
void disp();
void play(int);
};
Puzzle::Puzzle(){
int i, j;
cnt = 0; // 解の数をクリア
cpm = sizeof(chip_data) / sizeof(chip);
// ボードの初期化
for(i = 0; i < Bw * Bh; i++){
board[i] = Fv;
}
for(i =0; i < Sh; i++){
for(j = 0; j < Sw; j++){
board[Sp + i * Bw + j] = 0;
}
}
// チップの使用フラグをクリア
for(i = 0; i < Fv; i++){
chip_use[i] = 0;
}
}
// パズルの表示
void Puzzle::disp(){
string ppp[] = {
"・", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"A", "B", "C", "D", "┃"
};
printf(" %d 回目( %5.3f 秒)\n",
cnt++, (float )clock() / CLOCKS_PER_SEC);
cout << "┏━━━━━━━━┓" << endl;
for(int y = 1; y < 9; y++){
for(int x = 0; x < 10; x++){
cout << ppp[board[y * Bw + x]];
}
cout << endl;
}
cout << "┗━━━━━━━━┛" << endl;
}
// パズルの探索
void Puzzle::play(int sp){
int idn, p1, p2, p3, p4;
// 探索場所の確認
if(board[sp + 1] != 0 && board[sp + Bw] != 0){
return;
}
for(int i = 0; i < cpm; i++){ // チップ数だけ確認
if(chip_use[chip_data[i].id] != 0){ // チップが使用中か確認
continue;
}
// チップが置けるか?
if( board[p1 = sp + chip_data[i].s1] != 0 ||
board[p2 = sp + chip_data[i].s2] != 0 ||
board[p3 = sp + chip_data[i].s3] != 0 ||
board[p4 = sp + chip_data[i].s4] != 0){
continue;
}
// チップの配置
idn = chip_data[i].id;
board[sp] = idn;
board[p1] = idn;
board[p2] = idn;
board[p3] = idn;
board[p4] = idn;
chip_use[idn] = 1;
// 次の空きを探す
int np = sp;
while(np++ < Mp){
if(board[np] == 0){
break;
}
}
if(np <= Mp){
play(np); // 次のチップを探索
}
else{
disp(); // 解を表示
}
// チップの除去
board[sp] = 0;
board[p1] = 0;
board[p2] = 0;
board[p3] = 0;
board[p4] = 0;
chip_use[idn] = 0;
}
}
// メイン・ルーチン
int main(){
Puzzle pzl;
pzl.disp();
pzl.play(Sp);
}
─────
過去記事で紹介したプログラムに比べて、処理に必要な時間を少し減らすことが出来ました。
さらに、処理を効率化する方法を研究したいと思います。
(by 心如)
コメント 0