はじめに
こんばんは。
Goの勉強しはじめてます。
基本的なところとかを少しづつやってるんですが、今回 Go言語 初心者向けハンズオン #2 に参加させていただきました。
このハンズオン自体 #2で、自分は今回初参加かつ、仕事が忙しくて #1の資料を見れていなかった(言い訳)ので、ちょっと転校生気分で参加しました。
しかもそんな状態なのに、あろうことか仕事の影響で遅れて参加するという更に転校生気分に拍車をかけつつの参加でした。
タイトルに「少しだけ」とつけたのは↑が理由です。
すでに結構進んでいて、ゴルーチンとかテストの説明を少し聞けたくらいでした。
ただ、最後の課題には間に合ったので、試行錯誤の結果を載せておきます。
課題の内容は以下。
- じゃんけんゲームを作ろう
- 会話ゲームを作ろう
ハンズオンで使用されたスライドに仕様も記載されています。
やってみた
自分の実力では制限時間が短かったので、時間内に出来たのは1だけでした。。
そのかわりテストとかも書いたりして、1は完全に終わらそうと頑張りました。
package main import ( "fmt" "math/rand" "strconv" "time" ) const ( // GU じゃんけんグー GU = iota // CHOKI じゃんけんチョキ CHOKI // PA じゃんけんパー PA ) const ( // DRAW 引き分け DRAW = iota // LOSE 負け LOSE // WIN 勝ち WIN ) // Player ユーザーの勝敗などを持つ構造体 type Player struct { winCount int loseCount int drawCount int } // executeCount 実行回数 const executeCount = 100 func main() { player := Player{ winCount: 0, loseCount: 0, drawCount: 0, } for i := 1; i <= executeCount; i++ { battle(&player) } drawResult(player) } // battle じゃんけん開始 func battle(player *Player) { playerHand := selectHand() enemyHand := selectHand() switch judge(playerHand, enemyHand) { case DRAW: player.drawCount++ case LOSE: player.loseCount++ case WIN: player.winCount++ } } // selectHand じゃんけんの手を決定する func selectHand() int { rand.Seed(time.Now().UnixNano()) return rand.Intn(2) } // judge 判定 // @see https://qiita.com/mpyw/items/3ffaac0f1b4a7713c869 func judge(playerHand int, enemyHand int) int { return (playerHand - enemyHand + 3) % 3 } // drawResult 勝敗結果表示 func drawResult(player Player) { fmt.Println("勝利=" + strconv.Itoa(player.winCount) + "回") fmt.Println("引分=" + strconv.Itoa(player.drawCount) + "回") fmt.Println("敗北=" + strconv.Itoa(player.loseCount) + "回") fmt.Println("-------------------------------") fmt.Println("合計=" + strconv.Itoa(executeCount) + "回") } => $ go run main.go 勝利=28回 引分=44回 敗北=28回 ------------------------------- 合計=100回
時間制限があったので焦ってしまい、当初 judge()
のロジックは完全にif文で泥臭くやってました(笑)
その後テストを書き始める前に、参考サイトを確認し編集しました。
(あー頭が良くなりたい)
以下はテストです。
package main import ( "strconv" "testing" ) func TestSelectHand_ありえない値(t *testing.T) { hand := selectHand() if hand != PA && hand != GU && hand != CHOKI { t.Error("selectHand()でとれるはずのない値が取れている => " + strconv.Itoa(hand)) } } func TestJudge_引き分けなのに引き分けではない(t *testing.T) { result := judge(0, 0) if result != DRAW { t.Error("引き分けのはずなのに引き分けではない => " + strconv.Itoa(result)) } } func TestJudge_負けなのに負けではない(t *testing.T) { result := judge(1, 0) if result != LOSE { t.Error("負けのはずなのに負けではない => " + strconv.Itoa(result)) } } func TestJudge_勝ちなのに勝ちではない(t *testing.T) { result := judge(2, 0) if result != WIN { t.Error("勝ちのはずなのに勝ちではない => " + strconv.Itoa(result)) } } func TestBattle(t *testing.T) { player := Player{ winCount: 0, loseCount: 0, drawCount: 0, } battle(&player) if player.drawCount == 0 && player.winCount == 0 && player.loseCount == 0 { t.Error("勝敗結果が登録されていない") } } => $ go test -v === RUN TestSelectHand_ありえない値 --- PASS: TestSelectHand_ありえない値 (0.00s) === RUN TestJudge_引き分けなのに引き分けではない --- PASS: TestJudge_引き分けなのに引き分けではない (0.00s) === RUN TestJudge_負けなのに負けではない --- PASS: TestJudge_負けなのに負けではない (0.00s) === RUN TestJudge_勝ちなのに勝ちではない --- PASS: TestJudge_勝ちなのに勝ちではない (0.00s) === RUN TestBattle --- PASS: TestBattle (0.00s) PASS ok _/path/to/study_01 0.057s
終わりに
スタッフで参加されていた@yukpizさんがQiitaに解答を載せてくれています。
正直2番の方は解答見てもちょっとわからなかったので、もうちょいゴルーチン・チャネルについて勉強しないとなと思いました。
また、懇親会で @yukpizさんとお話させてもらい、エンジニアの登壇を応援する会を教えてもらいました。
slackチームにも参加させていただきました。
自分が運営している 週1でブログ書くslackチームに入ってくれている人たちも何人かいらして、面白かったですw
せっかくslackチームにも入ったので、来年こそは登壇を経験したいと思います。
ではでは。