プチメタ3.0

刺激を受けた物事に対する感想や考察、資産運用や英語学習、自己成長に関することなど。


【ゲーム業界志望者向け】プログラミングWeb試験に必要な知識まとめ


ゲームプログラマーを目指す学生が企業に応募するときは
自作のゲームプログラムを求められることがほとんどだが、
これに加えて筆記試験を受けさせられることがよくある。


最近はWeb試験の一種であるコーディングテストがよく使われていて、
ブラウザ上で直接プログラミングし、
指示された動きをするかをテスト実行した上で提出する。


ただ、このシステム自体に割とクセがあり、
3Dゲームをバリバリ作れる技術があったとしても
コーディングテストで脱落することが多い。


これは普段触っているゲームプログラミングと比べて
あまりに触り心地が違うのが原因と思われ、
その試験で本来問われている内容ではなく
もっと根本的な部分で失敗していたりする。


そこでそういったコーディングテストに挑む前に
準備しておく方がいい基礎知識についてまとめておく。

原始的な入出力処理に慣れておく

ゲームプログラムの出力は画像が原則であり、
タイトルロゴやスコアのような文字も
そういう画像を用意して表示しているだけだ。


また、プレイヤーからの入力はキーボードやマウス、
コントローラーなどを経由して行われるため、
特定のキーが押されているかどうかの判定しかしない。


しかしコーディングテストでは
std::coutとstd::cinあたりの原始的な入出力処理が使われており、
入学当初の授業で扱ったような手法を求められると
使い慣れていないだけにかなり戸惑う。


そこでcinとcoutの基本的な使い方を
しっかり復習しておくことが重要になる。


#include <iostream>
void main()
{
	int age;
	std::cin >> age;
	if(age >= 18)
	{
		std::cout << "大人です" << std::endl;
	}else{
		std::cout << "未成年です" << std::endl;
	}
}
  • 「iostream」のインクルードが必要
  • 「std::cin >> 変数」でキー入力された情報を変数に代入
  • 「std::out << 文字列」「std::out << 変数」で指定した内容を文字表示
  • 「std::endl」を出力すると改行

 

#include <iostream>
using namespace std;
void main()
{
	int age;
	cin >> age;
	if(age >= 18)
	{
		cout << "大人です" << endl;
	}else{
		cout << "未成年です" << endl;
	}
}

いちいち「std::」と書かなくていいように
「using namespace std;」が宣言されていることも多い。


データの入出力がうまくできないと
問題の本質部分にまったく挑戦できないので
cinとcoutの使い方をおさらいしておく方がよい。


paiza.jp


模擬的なデータが自動でプログラムに渡される

実際にプログラムを実行したときは
数値などのデータを人間が入力する必要があるが、
コーディングテストではそこが自動的に行われるようになっている。


たとえば前述のプログラムは
入力された年齢が成人かどうかを判別するものだが、
この年齢入力の部分が自動で行われるのだ。




また、いろいろな値を入力したパターンが試されるため、
特定の数値のときだけ期待通りの結果になってもダメで、
考えられるいろいろな入力データに対応できている必要がある。

最初に書かれているプログラムを使う必要はない

問題に取り掛かった段階で、ある程度のプログラムが
最初から書かれていることがよくある。


#include <iostream>
#include<string>
using namespace std;
void main()
{
	//ここにプログラムを書きましょう!
	string str;
	getline(cin, str);
	cout << "文字が表示されます" << endl;
}

なんとなく、ここに追記するばかりで
もともとのプログラムを書き替えてはいけないような気になるが、
それだと記述できる内容が限定されて逆に苦労する。


#include <iostream>
#include<string>
using namespace std;
void main()
{
	string str;
	getline(cin, str);
	cout << atoi(&str[0]) * 10 << endl;
}

たとえば数値が入力されるのにstring型で受け取ると
そのままでは数値として利用できなくなる。
そうなると文字列を数値に変換するatoi系の関数や
string型をchar型配列として扱うための
ポインタ表現(またはc_str関数)などを思い出す必要があり、負担が増える。


もともと書かれているのはただのサンプル表記であって
特に気にせず削除してしまって構わないし、
その方が圧倒的に楽に解決することがある。


#include <iostream>
using namespace std;
void main()
{
	int no;
	cin >> no;
	cout << no * 10 << endl;
}

入力されるものが数値に限られるなら
そのままint型の変数で受け取った方が楽だ。
余計なことで悩まなくて済むよう、
最初に書いてある内容は自由に削除していいと認識すべきだ。

複数の入力データの扱いに慣れておく

ひとつの数値だけが入力されるのではなく、
複数のデータがスペース区切りで入力されることがある。
その際はcin関数に複数の変数を指定することができる。


#include <iostream>
using namespace std;
void main()
{
	int math, sci, eng;
	cin >> math >> sci >> eng;
	
	cout << "合計得点は" << ( math + sci + eng ) << endl;
}

これだけで3つの値が3つの変数に入ってくれる。


下手にgetline関数などで受け取ってしまうと、
3つの数値を含む連結された文字列を
スペースごとに区切って取り出す必要が出てくるので
それだけでかなり複雑な処理になってしまう。
単にcinを連続して使うだけでいいことは覚えておいた方がよい。

入力データの個数が変化する場合への対応

よくあるのが入力データの個数が変わる場合だ。
たとえば最初に人数を入力させ、
そのあと各自のデータを入力させる場合などは
可変長配列クラスであるstd::vectorなどを利用するとよい。


#include <iostream>
#include <vector>
using namespace std;
void main()
{
	//人数を取得
	int num;
	cin >> num;
	
	//人数分のデータを取得
	vector<int> income(num);
	for(int i = 0; i < num; i++)
	{
		cin >> income[i];
	}
	
	//ソート
	for(int i = 0; i < num - 1; i++)
	{
		for(int k = i + 1; k < num; k++)
		{
			if(income[i] < income[k])
			{
				int tmp = income[i];
				income[i] = income[k];
				income[k] = tmp;
			}
		}
	}

	cout << "高い順に表示" << endl;
	for(int i = 0; i < num; i++)
	{
		cout << income[i] << endl;
	}
}
  • 「vector」のインクルードが必要
  • 「vector<型> 変数名(個数)」で指定された型の配列を指定された個数分宣言できる

ソート処理が必要になる問題も多いので、
一番簡単なバブルソートの処理を覚えておくと役立つ。

文字列の扱いにも慣れておく

入力データが文字列であることも多いので
std::stringの扱いにも慣れておく方がよい。


#include <iostream>
#include <string>
using namespace std;
void main()
{
	string name;
	cin >> name;
	
	//逆から表示
	for(int i = name.size() - 1; i >= 0; i--)
	{
		cout << name[i];
	}
}
  • 「string」のインクルードが必要
  • 文字数はsize関数で取得
  • 末端を示す「¥0」のために1文字使われる
  • 入力データは半角文字限定の場合が多い

 

#include <iostream>
#include <string>
using namespace std;
void main()
{
	int num;
	cin >> num;

	string str;
	str = "入力値は" + to_string(num) + "です";

	cout << str;
}
  • 数値をstring型として扱う場合はto_string関数を使う

 

#include <iostream>
#include<string>
using namespace std;
void main()
{
	string str;
	cin >> str;

	int num;
	num = atoi(&str[0]);
	num *= 10;

	cout << num << endl;
}
  • string型を数値扱いしたい場合は「&変数名[0]」でchar型ポインタを取り出してatoi関数に渡す

 

項目別の集計が必要な場合への対応

入力された項目の出現数を数えるなど、
項目別の管理が必要な場合は
連想配列クラスであるstd::mapを利用するとよい。


#include <iostream>
#include <map>
using namespace std;
int main(void){
    int num;
    cin >> num;
    
    map<int, int> list; //キーと値の型は自由に設定可能
    for(int i = 0; i < num; i++)
    {
        int tmpNo;
        cin >> tmpNo;

        if(list.find(tmpNo) == list.end()) //キーが存在しない
        {
            list[tmpNo] = 1; //新たなキーを追加
        }else{
            list[tmpNo]++;
        }
    }
    
    for(auto itr = list.begin(); itr != list.end(); ++itr)
    {
        cout << itr->first << "の出現数は" << itr->second << endl;
    }
}
  • 「map」のインクルードが必要
  • find関数でend()が返されたら該当項目は記録されていない
  • 各項目を順に処理していくときはbegin関数でイテレータを取得する
  • イテレータのfirstがキー(項目名)、secondが値

 

Visual Studioにコマンドプロンプトが付属している

実際にこういった原始的なプログラムを試したい場合、
Microsoft Visual Studioをインストールすれば
セットでコマンドプロンプトも付いてくる。




Windowsのスタートメニューの中のVisual Studioフォルダにある
「Developer Command Prompt for VS」を起動。




真っ黒なウィンドウが開くので
cdコマンドで適当なフォルダに移動する。


C:\cpp>cl/EHsc test.cpp

Microsoft(R) C/C++ Optimizing Compiler Version 19.34.31933 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

test.cpp
Microsoft (R) Incremental Linker Version 14.34.31933.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:test.exe
test.obj

C:\cpp>test
40
大人です

C:\cpp>

あとは「cl/EHsc ファイル名」で対象ファイルをコンパイル。
エラーが出なければ実行ファイルが作られるので、
実行した上で適当な値を入力して結果を確認できる。

paizaなら無料で実践トレーニングができる


paiza.jp


コーディングテストのシステムに慣れるためにも
実践環境で訓練するのが一番だが、
無料で試せる中ではpaizaが最適だろう。


会員登録は必要だが、大量の問題が用意されており、
さまざまなプログラミング言語に対応している。


Dランク問題は非常に単純なプログラムで済むので
まずはこれでシステムに慣れたあと、
就活生ならとりあえずCランク問題まで解けるようになっておきたい。

まとめ

私自身がpaizaの問題を数十問ほど解いてみて
その中で必要になった知識やポイントをまとめてみた。


問題が問おうとしている本質的な部分がわからないならともかく、
単にコーディングテストに不慣れなせいで
本来の能力が発揮できずに不合格になるのはもったいないので、
ゲームプログラマー志望であっても
上記のような知識を身につけておく方が安全だろう。

総アクセス数