にもっくん?
何をとちくるったのか、amazonのリコメンドエンジンが薦めてきたので、買ってしまった。
- 作者: 平山尚
- 出版社/メーカー: 秀和システム
- 発売日: 2008/11/14
- メディア: 単行本
- 購入: 112人 クリック: 3,473回
- この商品を含むブログ (193件) を見る
できれば一旦本を閉じて、自力で作ってみてほしい。馬鹿にするなと思うかもしれないが、実際にやってみると結構苦労するはずだ。一時間でできれば大した物だし、半日で終わればとりあえずは問題ないだろう。しかし二日以上かかるようならちょっと焦った方が良いかもしれない。
とか挑発的な事が書いてある。やらいでか!
やぱりC++かな?
この本の趣旨がどうも、プログラムはC++で、みたい。うーんちゃんと体得できてないのだよなー。1時間!1時間!、とそればかり考えながら必死になってスタート。まあいいや、設計とかまじめにしない。とにかく汚くても良いから書く。としてみた。
なんとか書ききる
なんとか書ききって文法エラーをはじくはじく。コードは最高に汚い。グローバル使いまくりの、定数ばかばか使ってサイズ決めうちだらけだし、vector使えば良いところを配列で流すし、string使えば良いところを・・・ともう最悪状態。ポインタとか参照とかで頭使いたくなかったので思わずnewせず全部実体。リークしまくりんぐ。
いや、こりゃ本当にひどい。けどなんとか動いてるみたい。2カ所程勘違いを直したら問題なく動いた。
さて、最初にtouchしておいたファイルとくらべてみると時間は。。。
- rw-r--r-- 1 kuro staff 0 12 16 01:43 start
- rwxr-xr-x 1 kuro staff 18424 12 16 03:44 nimotsukun*
ぬわーーー、二時間超えた ToT 二時間もかけてこんな汚いコード吐いてるようではダメだ。もっと精進しよう。けどまあ久々に面白かった。
wsadで上下左右。cin使ってるのでそのままだといちいちenterする必要あり。UN*Xライクな環境なら stty -icanon をするとリアルタイムに拾ってくれて幸せかも。まあ、遊んでくれる奇特な方がいればご参考にどうぞ。
Sprite.h
#ifndef __SPRITE__ #define __SPRITE__ struct Sprite : public Point { char face; }; #endif
Point.h
#ifndef __POINT__ #define __POINT__ struct Point { int x; int y; Point() { x = y = 0; } Point(int x,int y) { this->x = x; this->y = y; } const Point& operator+(const Point& p) const { return *(new Point(this->x + p.x, this->y + p.y)); } }; #endif
GameBoard.h
#include <iostream> #include "Point.h" #include "Sprite.h" using std::cout; using std::endl; class GameBoard { static const int N_SPRITE = 128; int width, height; char* screen; Sprite sprite_list[N_SPRITE]; int sprite_max; public: GameBoard(int width, int height) { this->width = width; this->height = height; this->sprite_max = 0; screen = new char[width*height]; init_screen(); } void load_map(char* p) { char* q = screen; for ( ; *p;) { *q++ = *p++; } } void init_screen() { char* p = screen; for (int i = 0; i < width*height; i++) { *p++ = ' '; } } bool inrange(const Point& p) const { return (p.x < 0 || p.x > width || p.y < 0 || p.y > height ) ; } char get(const Point& p) const { if (inrange(p)) throw "out of range"; return *(screen + p.x + p.y*width); } void set(const Point& p, char c) { if (inrange(p)) throw "out of range"; *(screen + p.x + p.y*width) = c; } void print() const { char* p = screen; cout << "\x1b[2J"; cout << "\x1b[1;1H"; for (int y = 0; y< height; y++) { for (int x = 0; x< width; x++) { int sp; for (sp = 0; sp < sprite_max; sp++) { if (x == sprite_list[sp].x && y == sprite_list[sp].y) { cout << sprite_list[sp].face; break; } } if (sp == sprite_max) cout << *p; ++p; } cout << endl; } } void clear_sprite() { for (int i=0; i< N_SPRITE; i++) { sprite_list[i].x = 0; sprite_list[i].y = 0; sprite_list[i].face = 0xff; } } int create_sprite(const Point& p, int c) { sprite_list[sprite_max].x = p.x; sprite_list[sprite_max].y = p.y; sprite_list[sprite_max].face = c; return sprite_max++; } void set_sprite(int no, const Point& p) { sprite_list[no].x = p.x; sprite_list[no].y = p.y; } };
nimotukun.cpp
#include <iostream> #include "GameBoard.h" using std::cin; using std::cout; const int width =10, height=10; char map[] = //0123456789 "##########" "# P#" "## # ##" "### ####" "### O ##" "####O ##" "## O O####" "## .####" "## ...##" "##########"; int keyin() { char c; cin >> c; return c; } struct Character : public Point { int id; Character& operator=(const Point& p) { this->x = p.x; this->y = p.y; } }; Character goods[32]; Character player; int ngoods; int OK = 0; int compile_map(GameBoard& board, char* map) { int n = 0; for (char* p = map; *p; p++) { if (*p == 'O' || *p == 'P') { Point pos = Point((p-map) % width, (p-map) / width); int id = board.create_sprite(pos, *p); if (*p == 'O') { goods[n].id = id; goods[n] = pos; n++; } else { player.id = id; player = pos; } *p = ' '; } } return n; } void make_board(GameBoard& board) { board.clear_sprite(); ngoods = compile_map(board, map); board.load_map(map); } int collision(const Point& p) { for (int i=0; i< ngoods; i++) { if (goods[i].x == p.x && goods[i].y == p.y) //collide! return i; } return -1; } bool free_or_canpush(GameBoard& board, const Point& from, const Point& diff) { Point dist = from + diff; int pushed; if ((pushed=collision(dist))>=0) { if (collision(dist+diff)>=0 || board.get(dist+diff) == '#') return false; if (board.get(goods[pushed]) == '.') --OK; goods[pushed] = goods[pushed] + diff; board.set_sprite(goods[pushed].id, goods[pushed]); if (board.get(goods[pushed]) == '.') ++OK; } return true; } main() { GameBoard board(width, height); make_board(board); bool cont = true; while (cont) { Point newpos; board.print(); if (OK == ngoods) { cout << "********* congraturation!!!! ********" << endl; break; } int c = keyin(); switch (c) { case 'd': newpos = Point(+1, 0); //right break; case 'a': newpos = Point(-1, 0); //left break; case 'w': newpos = Point( 0,-1); //up break; case 's': newpos = Point( 0,+1); //down break; case 'q': cont = false; //quit; break; default: break; } char there = board.get(player+newpos); if ((there == '.' || there == ' ') && free_or_canpush(board, player, newpos)) player = player+ newpos; board.set_sprite(player.id, player); } // exit return 0; }