LoginSignup
2
5

More than 3 years have passed since last update.

「ゲームプログラマになる前に覚えておきたい技術」のお勉強を開始!

Posted at

今回は初投稿ということで投稿練習がてらほぼ自己紹介です。
最後に本書の第1章の課題でもある自作の倉庫番のコードがあります。

筆者のスペック
  • 千葉大学 融合理工学府 数学情報科学専攻 数学情報数理学コース 1年 (まあ簡単に言うと数学科のM1です)
  • 大学のゼミではHaskellを勉強、独学でC++の入門書を7~8割くらい読んだ。
  • 数学は圏論を独学中ですが全く分からないので心が折れてます
  • 競技プログラミングをやってます。AtCoderで茶色です。
  • パソコン関係や通信等の情報関係の知識が完全に初心者(自宅にWi-Fiを設置できるという事実を「去年」友人に指摘され初めて気づきました)
  • 水樹奈々さんが好き

まあこんなところでしょうか。
ゲームを作ろうと思ったきっかけですが、正直に言うと就活に向けて何か成果物が欲しかったからです。本当はゲーム業界ではないIT企業などの就職も十分に考えているので成果物はゲームではないほうが無難なのですが、今現在プログラミングで何か作ろうと考えたときに一番最初に浮かんだのがゲームだったのです。まあ最悪どっちも作っちゃえばいいわけだし!?
ということで
最近ゲーム制作に取り組み始めた筆者ですが、そのお勉強をするにあたってこの「ゲームプログラマになる前に覚えておきたい技術」(著・平山尚)という本を買いました。評価も高く、セガの新人教育プログラムを基にしているそうです。なんとも入門書という感じがしますね!

ここに最初の倉庫番の自作コードを何となく置いておきます。
製作時間は動かすのに5時間+改良に1時間=6時間です。
本当は3時間くらいで行けると思っていましたが、まずまずといったところでしょうか。

soukoban.cpp

#include <bits/stdc++.h>
using namespace std;

const int WIDTH  = 8;
const int HEIGHT = 5;

vector<vector<char>> defaultstage = {
    {'#','#','#','#','#','#','#','#'}
  , {'#',' ','.','.',' ','p',' ','#'}
  , {'#',' ','o','o',' ',' ',' ','#'}
  , {'#',' ',' ',' ',' ',' ',' ','#'}
  , {'#','#','#','#','#','#','#','#'}
};

vector<vector<char>> update(char input,vector<vector<char>> stage,pair<int,int> person,bool personIsbig);
void drawstage(vector<vector<char>> stage);
pair<bool,pair<int,int>> personcheck(vector<vector<char>> stage);
vector<vector<char>> moveWithInput(char input,int px,int py,vector<vector<char>> stage,bool personIsbig);
void completecheck(vector<vector<char>> stage);

int main() {
  vector<vector<char>> stage(HEIGHT,vector<char> (WIDTH,' '));
  for(int i=0;i<HEIGHT;i++){
    for(int j=0;j<WIDTH;j++){
      stage[i][j] = defaultstage[i][j];
    }
  }
  drawstage(stage);

  while(1){
    char input;
    cin >> input;
    bool personIsbig = personcheck(stage).first;
    pair<int,int> person = personcheck(stage).second;
    vector<vector<char>> newstage = update(input,stage,person,personIsbig);
    for(int i=0;i<HEIGHT;i++){
      for(int j=0;j<WIDTH;j++){
        stage[i][j] = newstage[i][j];
      }
    }
    drawstage(stage);
    completecheck(stage);
  }
}

void completecheck(vector<vector<char>> stage){
  for(int i=0;i<HEIGHT;i++){
    for(int j=0;j<WIDTH;j++){
      if(stage[i][j] == 'o') return;
    }
  }
  cout << "Congratulation!!" << endl;
}

pair<bool,pair<int,int>> personcheck(vector<vector<char>> stage){
  for(int i=0;i<HEIGHT;i++){
    for(int j=0;j<WIDTH;j++){
      switch (stage[i][j]){
        case 'p': return make_pair(false,make_pair(j,i));
        case 'P': return make_pair(true,make_pair(j,i));
      }
    }
  }
  cout << "PersonCheck Error" << endl;
  return make_pair(false,make_pair(-1,-1));
}

void drawstage(vector<vector<char>> stage){
  for(int i=0;i<HEIGHT;i++){
    for(int j=0;j<WIDTH;j++){
      cout << stage[i][j];
    }
    cout << endl;
  }
}

vector<vector<char>> update(char input,vector<vector<char>> stage,pair<int,int> person,bool personIsbig){
  int px = person.first;
  int py = person.second;
  return moveWithInput(input,px,py,stage,personIsbig);
}

//personが立ち去った後の、立っていた点の処理
vector<vector<char>> leave(int px,int py,vector<vector<char>> stage,bool personIsbig){
  if (personIsbig) stage[py][px] = '.';
  else stage[py][px] = ' ';
  return stage;
}

vector<vector<char>> move(int px,int py,int dpx,int dpy,vector<vector<char>> stage,bool personIsbig){
  switch (stage[py+dpy][px+dpx]){
    case ' ':
      stage[py+dpy][px+dpx] = 'p';
      return leave(px,py,stage,personIsbig);
    case '.':
      stage[py+dpy][px+dpx] = 'P';
      return leave(px,py,stage,personIsbig);
    case 'O':
      switch (stage[py+2*dpy][px+2*dpx]) {
        //'#','o','O'の場合はその場に残る
        case ' ':
          stage[py+2*dpy][px+2*dpx] = 'o';
          stage[py+dpy][px+dpx] = 'P'; //'o'との違い
          return leave(px,py,stage,personIsbig);
        case '.':
          stage[py+2*dpy][px+2*dpx] = 'O';
          stage[py+dpy][px+dpx] = 'P'; //'o'との違い
          return leave(px,py,stage,personIsbig);
      }
    case 'o':
      switch (stage[py+2*dpy][px+2*dpx]) {
        //'#','o','O'の場合はその場に残る
        case ' ':
          stage[py+2*dpy][px+2*dpx] = 'o';
          stage[py+dpy][px+dpx] = 'p'; //'O'との違い
          return leave(px,py,stage,personIsbig);
        case '.':
          stage[py+2*dpy][px+2*dpx] = 'O';
          stage[py+dpy][px+dpx] = 'p'; //'O'との違い
          return leave(px,py,stage,personIsbig);
      }
    }
    return stage;
}

//personの移動
vector<vector<char>> moveWithInput(char input,int px,int py,vector<vector<char>> stage,bool personIsbig){
  switch (input) {
    case 'a': return move(px,py,-1,0,stage,personIsbig);
    case 'w': return move(px,py,0,-1,stage,personIsbig);
    case 's': return move(px,py,0,1,stage,personIsbig);
    case 'd': return move(px,py,1,0,stage,personIsbig);
  }
}

2
5
1

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
2
5