#実践編
最近、こんな問題がTwitterで話題になってました。
というわけで、この問題をオブジェクト指向でコーディングするとどんな感じになるのか。やってみたいと思います。
理論編から読みたいかたはコチラ。
(1)オブジェクトを洗い出す
問題文を見ると、「人(プレイヤーと呼びましょう)」と「カード」が登場していますね。これが今回のオブジェクトたちです。
class Player {
}
class Card {
}
(2)各オブジェクトのプロパティを洗い出す
プレイヤー
プレイヤーのプロパティは、「プレイヤーの名前(A,B,C)」「額にかざしているカード(ランダムで1枚引いたやつ)」ですね。
class Player {
name;
card;
}
カード
カードのプロパティは、「数字(1~5のどれか)」ですね。
class Card {
number;
}
(3)各オブジェクトのメソッドを洗い出す
プレイヤー
プレイヤーのメソッドは、「ランダムにカードを1枚のカードを引いて額にかざす」と「MAX, MID, MIN, ?のいずれかを回答する」ですね。
class Player {
name;
card;
draw(cards) { }
answer(cards) { }
}
カード
カードにメソッドは、ありません!だって現実世界のカード、自分から動いたりしないですもの。
class Card {
number;
//メソッドはなし!
}
(4)オブジェクト間のメッセージを洗い出す
今回のメッセージは「プレイヤーが相手のカードを見る」と「プレイヤーがカードの数字を見る」ですね。
class Player {
name;
card;
draw(cards) { }
answer(cards) {
//カードオブジェクトの数字を確認する。
}
}
以上が、オブジェクト指向をコードに落とし込むまでの手順になります。慣れてしまえばとても便利なので、是非マスターしてくださいね!
後書き
C#を例にコード全体の全体像を書いてみました。参考までに読んでみてください。
Hello.cs
using System;
using System.Collections.Generic;
class Hello {
public static void Main(){ //つまるところ、メイン関数はフローチャートなのだ。
//カードを用意
int num_cards = 5;
List<Card> cards = new List<Card>();
for(int i = 0; i < num_cards; i++) {
int number = i + 1;
cards.Add(new Card(number));
}
//プレイヤーを用意
int num_players = 3;
List<Player> players = new List<Player>();
for(int i = 0; i < num_players; i++) {
string name = ToAlphabet(i);
players.Add(new Player(name));
}
if(num_cards < num_players) {
Console.WriteLine("エラーだよ!");
return;
}
//各プレイヤーがカードを引く
foreach(Player p in players) {
p.Draw(cards); //カードを引くのでカードを引数で渡す
}
//プレイヤーが順番に回答してゆく
foreach(Player p in players) {
string answer = p.Answer(players); //他のプレイヤーの様子を見るのでプレイヤーを引数で渡す
Console.Write("{0}=>{1}", p.name, answer);
if(answer == "?" && players[players.Count-1] != p) { //次の回答者がいたらカンマを出力して続行
Console.Write(", ");
}
else { //次の回答者がいなかったらおしまい。
Console.WriteLine();
break;
}
}
}
//数字をアルファベットに変換!
static string ToAlphabet(int number) {
string alphabet = "";
do {
alphabet = Convert.ToChar(number % 26 + 0x41) + alphabet;
} while((number=number/26-1) != -1);
return alphabet;
}
}
class Card {
private int _number;
public int number {
get { return this._number; }
}
public Card(int number) {
this._number = number;
}
//現実世界のカードは自分から動かないのでメソッドを持たない!
}
class Player {
private Card _card;
public Card card {
get { return this._card; }
}
private string _name;
public string name {
get { return this._name; }
}
public Player(string name) {
this._name = name;
}
//カードを一枚引いて額にかざす
public void Draw(List<Card> cards) {
Random random = new Random(Environment.TickCount);
int index = random.Next(cards.Count);
this._card = cards[index];
cards.RemoveAt(index);
}
//MAX, MID, MIN, ?
public string Answer(List<Player> players) {
//ここがこの問題の肝となるアルゴリズムです!
//是非チャレンジしてみてくださいね!
return "?";
}
}
以上です!