这是indexloc提供的服务,不要输入任何密码
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
5b7e357
コンパイルが通らない箇所をコメントアウト
tksmaru May 10, 2014
8e75fdc
target/配下はリポジトリ管理しない
tksmaru May 10, 2014
15cad09
プレーヤー人数を入力させる部分を作成。コンパイルエラーになる箇所をコメントアウト。Springのリソースを読み込む箇所を一旦コメントアウト。
tksmaru May 10, 2014
317bfae
ルールを別クラスに外出し
tksmaru May 10, 2014
922c0d7
課題1が最低限動くとこまでとりあえず作った(要大リファクタリング)
tksmaru May 15, 2014
27a8cb0
最低限ゲームが成立するようにした
tksmaru May 17, 2014
1832bb8
リファクタリングと修正
tksmaru May 18, 2014
ee5fcc2
ルールのコメントを追加
tksmaru May 18, 2014
3d389dd
場に対する操作メソッドをパッケージプライベートに変更(GM経由で呼び出すことを想定)
tksmaru May 18, 2014
a6e2493
プレーヤーに対する操作メソッドをパッケージプライベートに変更(GM経由で呼び出すことを想定)
tksmaru May 18, 2014
48bfb73
列に対する操作メソッドをパッケージプライベートに変更(GM経由で呼び出すことを想定)
tksmaru May 18, 2014
d5c4ff1
山札に対する操作をGM経由に想定。コメントを記載。
tksmaru May 18, 2014
63cfeb0
コマンドラインでの処理をリファクタリング
tksmaru May 18, 2014
c42e8e4
import対象を明示
tksmaru May 18, 2014
bb8e912
Fieldから直接Lineを取得するためのメソッド&LineのdeepCopyメソッドを追加
tksmaru May 19, 2014
2816d22
local変数を直感的に理解しやすい単語に変更
tksmaru May 19, 2014
7a3d853
UserをPLayerにリファクタリング
tksmaru May 20, 2014
b39f410
fix typo
tksmaru May 20, 2014
bd6b408
カードごとの牛の数には法則があったので、デッキを初期化する際にその法則を適用する。
tksmaru Jun 5, 2014
0dd4dfa
通常のカードの牛の数は1に設定。
tksmaru Jun 5, 2014
73db00c
各列に並んでいる牛の数の合計が最も少ない列番号を取得できるようにする。
tksmaru Jun 5, 2014
782f7b6
列に並んでいる牛の数の合計を取得できるようにする。
tksmaru Jun 5, 2014
84ff618
ユーザが出したカードが、場に置かれている各列の最後尾のカードよりも小さい場合に、
tksmaru Jun 5, 2014
1e134bd
・ユーザが出したカードが、場に置かれている各列の最後尾のカードよりも小さい場合に、
tksmaru Jun 5, 2014
c4b3b4d
牛の数を取得する部分を別メソッドに切り出した。
tksmaru Jun 5, 2014
ab5c8d4
カードの初期化時にcowをセットするように変更
tksmaru Jun 6, 2014
2383467
Byteだと列の牛の数の合計値よりも小さくなる可能性があるのでIntegerに変更
tksmaru Jun 15, 2014
800f878
手札をSortedMapで保持するようにした。\n場にカードを置くロジックをまとめた。\nその他リファクタリング多数。
tksmaru Jun 15, 2014
82e8094
いろいろリファクタリング
tksmaru Jun 18, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
*.iml
*.iml

target/
.idea/
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>

<build>
Expand Down
216 changes: 216 additions & 0 deletions src/main/java/com/masudak/nimmt/NimmtCli.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package com.masudak.nimmt;


import com.masudak.nimmt.core.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;

/**
* Nimmtをコマンドラインで遊ぶためのユーザインタフェースです
*
* @author tksmaru
*/
public class NimmtCli {

private Prompt prompt = new Prompt();

public static void main(String[] args) {
System.out.println("nimmt Start!!");
try {
new NimmtCli().play();
} catch (GameException e) {
System.out.println(e.getMessage());
System.exit(1);
}
}

public void play() throws GameException {

final int numberOfPlayer = prompt.getNumberOfPlayer();
GameMaster gameMaster = GameMaster.newGame(numberOfPlayer);

// 出力
Player nonNpcPlayer = gameMaster.getPlayer(Rule.PLAYER_ID);
prompt.showStatus(nonNpcPlayer);
prompt.showField(gameMaster.getField());

while (nonNpcPlayer.hasHand()) {

int cardNumber = prompt.getCardFromHands(nonNpcPlayer);
SortedMap<Card, Player> open = gameMaster.openHand(cardNumber);

prompt.showOpen(open.keySet());

// 1ターン
for (Map.Entry<Card, Player> entry : open.entrySet()) {
Card card = entry.getKey();
Player player = entry.getValue();
System.out.println("Dealing => playerId : " + player.getId() + ", card : " + card.getNumber());
int line;
if (card.getNumber() < gameMaster.getMinimum()) {
line = getLineByPlayerChoice(player, gameMaster.getField());
} else {
line = gameMaster.getLineToAddLast(card.getNumber());
}
gameMaster.putCardAndUpdate(line, card, player.getId());
}

System.out.println("1巡が終わった状態");
prompt.showField(gameMaster.getField());
prompt.showStatus(nonNpcPlayer);
}

System.out.println("============= Game is Over. =============");
prompt.showScore(gameMaster.getScores());
prompt.closeStream();
}

/**
* プレーヤーの選択でカードを置く列の列番号を取得します。
*
* @param user プレーヤー
* @param field 場
* @return 列番号
*/
private int getLineByPlayerChoice(Player user, Field field) {
if (user.isNpc()) {
// NPCは牛の合計数が最も小さい列を選択する
return field.getLineWithMinCows();
} else {
// ユーザに選択させる
prompt.showField(field);
return prompt.getIndexOfLine();
}
}

/**
* コマンドプロンプト
*/
class Prompt {

private BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

/**
* 標準入力からプレーヤーの人数(2-10)を取得します。<br />
* 入力値が不正の場合は3回までリトライさせます。<br />
* 3回リトライしても正しい値が入力されない場合は{@link GameException}をスローします。
*
* @return プレーヤー人数(2-10)。
* @throws GameException リトライに3回失敗した場合
*
*/
int getNumberOfPlayer() throws GameException {
int retryCount = 0;
while (retryCount < 3) {
System.out.println("Input number of player (2-10)");
int number = getNumberFromInput();
if (Rule.isValidNumberOfPlayers(number)) {
return number;
}
System.out.println("Number of player should be in 2-10");
retryCount++;
}
throw new GameException("プレーヤーの人数が正しく入力されませんでした。");
}

/**
* @return 標準入力から得られた数字。数字以外を入力した場合は-1(無効な数)を返す。
*/
private int getNumberFromInput() {
try {
return Integer.parseInt(in.readLine());
} catch (Exception e) {
return -1;
}
}

/**
* プレーヤーの手札にあるカードのうち、場に出すカードの番号を取得します。
*
* @param player プレーヤー
* @return ユーザの手札のインデックス番号(0-{その時点のユーザの手札の枚数-1})
*/
int getCardFromHands(Player player) {
System.out.println("choose your card in you hand.");
while(true) {
int number = getNumberFromInput();
if (player.hasCard(number)) {
System.out.println("You have choose " + number);
return number;
}
System.out.println("Player does not have a card you have chosen. Choose again");
}
}

/**
* ユーザが手札を置く列を取得します。(0-3を想定)<br />
* 正しい値が入力されるまでプロンプトは繰り返し表示されます。
*
* @return 列のインデックス番号(0-3を想定)
*/
int getIndexOfLine() {
System.out.println("choose line. [index]");
while(true) {
int index = getNumberFromInput();
if (Rule.isValidFieldIndex(index)) {
System.out.println("You have choose [index]:" + index);
return index;
}
System.out.println("Input should be in 0-3. Choose again");
}
}

void closeStream() {
try {
in.close();
} catch (IOException e) {
// ignore
}
}

void showStatus(Player player) {
System.out.println("----- status now. -----");
StringBuilder builder = new StringBuilder();
builder.append("playerId : " + player.getId() + "\n");
builder.append("cows : " + player.getCow() + "\n");
builder.append("your hands : \n");
for (Card card : player.getHands()) {
builder.append(card.getNumber() + "(" + card.getCow() + ") ");
}
System.out.println(builder.toString());
System.out.println("-----------------------");
}

void showField(Field field) {
System.out.println("----- Cards on field now. -----");
for (Line line : field.showLines()) {
System.out.print(line.getId() + ": ");
for (Card card : line.getCards()) {
System.out.print(card.getNumber() + "(" + card.getCow() + ") ");
}
System.out.println();
}
System.out.println("-------------------------------");
}

void showScore(List<Score> scores) {
for (Score score : scores) {
System.out.println(score.getPlayerId() + ": " + score.getCow());
}
}

public void showOpen(Set<Card> cards) {
System.out.println("Cards to deal.");
for (Card card: cards) {
System.out.print(card.getNumber() + " ");
}
System.out.println();
}
}
}
62 changes: 62 additions & 0 deletions src/main/java/com/masudak/nimmt/core/Card.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.masudak.nimmt.core;

/**
* Nimmtにおける1枚のカードを表します
*
* @author tksmaru
*/
public class Card implements Comparable<Card> {
/** カードの番号 */
private int number;
/** 牛の数 */
private int cow;

public Card(int number) {
this.number = number;
this.cow = getCow(number);
}

/**
* カード番号に伴う牛の数を取得します。
*
* @param number カード番号
* @return 牛の数。
*/
private int getCow(int number) {
int cow = 0;
if (number % 11 == 0) cow += 5;
if (number % 10 == 5) cow += 2;
if (number % 10 == 0) cow += 3;
if (cow == 0) cow = 1;
return cow;
}

/**
* カードの番号を取得します。
*
* @return カードの番号
*/
public int getNumber() {
return number;
}

/**
* カードの牛の数を取得します。
*
* @return 牛の数
*/
public int getCow() {
return cow;
}

@Override
public int compareTo(Card card) {
if (this.number > card.getNumber()) {
return 1;
} else if (this.number < card.getNumber()) {
return -1;
} else {
return 0;
}
}
}
61 changes: 61 additions & 0 deletions src/main/java/com/masudak/nimmt/core/Deck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.masudak.nimmt.core;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Nimmtの山札を表します。<br />
* 山札に対する全ての操作は{@link GameMaster}を介して行われます。
*
* @author tksmaru
*/
class Deck {

/** 山の先頭 */
private static final int HEAD = 0;

private static Deck instance;

/** 山札に置かれているカード */
private List<Card> cards;

/**
* 山札を初期化します。<br />
*/
private Deck() {
cards = new ArrayList<Card>(Rule.NUMBER_OF_CARDS);
for (int i = 1; i <= Rule.NUMBER_OF_CARDS; i++) {
cards.add(new Card(i));
}
Collections.shuffle(cards);
}

public static Deck getInstance() {
if (instance == null) {
instance = new Deck();
}
return instance;
}

/**
* 山札から指定した枚数カードを抜き取ります。
*
* @param number 抜き取るカードの枚数
* @return 山札から抜き取られたカードの一覧
*/
public List<Card> getCards(int number) {
List<Card> hand = new ArrayList<Card>(cards.subList(HEAD, number));
cards.subList(HEAD, number).clear();
return hand;
}

/**
* 山札から1枚カードを抜き取ります。
*
* @return カード
*/
public Card get() {
return cards.remove(HEAD);
}
}
Loading