[Go] Go言語で簡単なじゃんけんプログラムを作成してみよう！（初心者向け）


## この記事の目的
Go言語に興味がある初学者の方が簡易なじゃんけんプログラムを理解することができる

## 何はともあれまずはコードを確認してみましょう！

```main.go
package main

import (
    "fmt"
    "math/rand"
    "time"
)

func main() {
    rand.Seed(time.Now().UnixNano())
    userChoice := getUserChoice()
    computerChoice := getComputerChoice()
    result := determineWinner(userChoice, computerChoice)
    displayResult(userChoice, computerChoice, result)
}

func getUserChoice() string {
    var choice string
    fmt.Println("じゃんけんを始めます！")
    fmt.Println("1: グー")
    fmt.Println("2: チョキ")
    fmt.Println("3: パー")
    fmt.Print("あなたの選択 (1/2/3): ")
    fmt.Scanln(&choice)

    switch choice {
    case "1":
        return "グー"
    case "2":
        return "チョキ"
    case "3":
        return "パー"
    default:
        fmt.Println("無効な選択です。1から3の数字を選んでください。")
        return getUserChoice()
    }
}

func getComputerChoice() string {
    choices := []string{"グー", "チョキ", "パー"}
    computerChoice := choices[rand.Intn(len(choices))]
    return computerChoice
}

func determineWinner(userChoice, computerChoice string) string {
    if userChoice == computerChoice {
        return "引き分け"
    }

    switch userChoice {
    case "グー":
        if computerChoice == "チョキ" {
            return "勝ち"
        }
        return "負け"
    case "チョキ":
        if computerChoice == "パー" {
            return "勝ち"
        }
        return "負け"
    case "パー":
        if computerChoice == "グー" {
            return "勝ち"
        }
        return "負け"
    }

    return "不明"
}

func displayResult(userChoice, computerChoice, result string) {
    fmt.Println("あなたの選択:", userChoice)
    fmt.Println("コンピュータの選択:", computerChoice)
    fmt.Println("結果:", result)
}
```
このプログラムはユーザーに出す手を選択させ、コンピュータもランダムに出す手を選びます
その後、勝敗を判定し結果を表示します

### 例
```
❯ go run main.go
じゃんけんを始めます！
1: グー
2: チョキ
3: パー
あなたの選択 (1/2/3): 3
あなたの選択: パー
コンピュータの選択: グー
結果: 勝ち
```

## コードの詳細をひとつずつピックアップしてみてみましょう
### func main()

ここでは、順に作成した関数を呼び出して処理を行なっています
```main.go
func main() {
    // 乱数生成器を初期化する
    rand.Seed(time.Now().UnixNano())

    // ユーザーに出す手を選択させる
    userChoice := getUserChoice()

    // コンピュータが出す手を選択する
    computerChoice := getComputerChoice()

    // 勝敗を判定する
    result := determineWinner(userChoice, computerChoice)

    // 結果を表示する
    displayResult(userChoice, computerChoice, result)
}
```


### func getUserChoice()

特に注目する点は以下になります
```main.go
// ユーザーに選択を入力するように促す
fmt.Print("あなたの選択 (1/2/3): ")  
// ユーザーの選択を標準入力から読み取る
fmt.Scanln(&choice)
```

ここで、あえて`fmt.Print`を使用しているのには理由があります
それは`fmt.Println`を使用してしまうと改行が自動で入り、ややみづらくなるからです

#### fmt.Printの場合
```
あなたの選択 (1/2/3): 3
```
#### fmt.Printlnの場合
```
あなたの選択 (1/2/3): 
3
```

細かいことですが、知っておくとお得です
また、`fmt.Scanln()`は標準入力を受け取り、指定した変数にその値を割り当てることができます

#### なぜchoiceに&記号がついているの？

`&choice`はGo言語でのアドレス演算子（アンド記号）を使用した表現です
この表現は変数`choice`のメモリアドレスを取得するものであり、関数に変数へのポインタ（メモリアドレスを指す参照）を渡すことができます
簡単にいうとアドレス演算子`&`を使用して変数のアドレスを取得し、それを関数に渡すことで関数内でその変数の値を変更できるようにする仕組みになります
ポインタについての詳細な説明は別記事に任せることにします
ポインタ・参照渡し・値渡しという概念があるんだなぁ程度でOKです！

### func getComputerChoice()
```main.go
func getComputerChoice() string {
    // コンピュータが選択できる手のリストを作成する
    choices := []string{"グー", "チョキ", "パー"}
    // ランダムに出す手を選択する
    computerChoice := choices[rand.Intn(len(choices))]

    return computerChoice
}
```
### func determineWinner(userChoice, computerChoice string)
ここは至ってシンプルで先述の関数二つの戻り値を比較しています

#### ちなみにfunc determineWinner(userChoice, computerChoice string) string {ってどうなってるの？

 ひとつ目のstringは引数`userChoice`と`computerChoice`の型を宣言しています
ふたつ目のstringはdetermineWinner()関数の戻り値の型を宣言しています

### func displayResult(userChoice, computerChoice, result string)
あとは結果を出力するだけですね！

## まとめ
簡単なじゃんけんのプログラムですが、Go初学者の方は書き方になれなかったと思います
こういった簡単なプログラムの例をこれからも投稿していこうと思っていますので何卒。。。