C#
オブジェクト指向

オブジェクト指向が5000%理解できる記事(実践編)


実践編

最近、こんな問題が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 "?";
}
}


以上です!