go 실습 숫자 야구

숫자 야구란?

  1. 두 사람이 각자 0~9 까지 3개의 숫자를 생각 한다. (생각한 숫자는 서로 알려주지 않는다.)
  2. 상대방이 내가 생각 한 숫자를 맞추기 위해 임의의 숫자를 3가지를 말한다.
  3. 이 때 만약 상대방이 말한 숫자와 내가 생각한 숫자의 자릿수와 숫자가 같다면 스트라이크 숫자만 같다면

ex)

  • 123 / 561 = 1볼
  • 123 / 132 = 1스트라이크 2볼
  • 123 / 123 = 3스트라이크 승리!
  1. 이 것을 서로 반복해 가면서 상대방의 숫자를 먼저 추리해 내는 게임

프로그램 만들기전 구상

  1. 컴퓨터가 무작위로 0~9의 숫자 3개를 정함
  2. 사용자 입력을 받음
  3. 입력 받은 숫자를 비교한뒤 결과를 출력
  4. 3스트라이크가 나올 때 까지 계속 반복한다.

프로그램 만들기

1. 큰 틀 잡기

package main

import (
	"fmt"
)

func main() {
	numbers := MakeNumbers() // 무작위 숫자 3개를 만든다.

	cnt := 0

	for {
		cnt++
		inputNumbers := InputNumbers() // 사용자의 입력을 받는다.

		result := CompareNumbers(numbers, inputNumbers) // 결과를 비교한다.

		PrintResult(result)

		if IsGameEnd(result) {
			break
		} // 3S 일경우 게임 끝}
	}
	fmt.Printf("%d번 만에 맞췄습니다.", cnt)
	//몇번만에 맞췄는지 출력
}

2.에러 없이 빌드되는 상태로 만들기

package main

import (
	"fmt"
)

func main() {
	numbers := MakeNumbers() // 무작위 숫자 3개를 만든다.

	cnt := 0

	for {
		cnt++
		inputNumbers := InputNumbers() // 사용자의 입력을 받는다.

		result := CompareNumbers(numbers, inputNumbers) // 결과를 비교한다.

		PrintResult(result)

		if IsGameEnd(result) {
			break
		} // 3S 일경우 게임 끝}
	}
	fmt.Printf("%d번 만에 맞췄습니다.", cnt)
	//몇번만에 맞췄는지 출력
}

func MakeNumbers() [3]int {
	var rst [3]int
	return rst
} // 0~9 사이의 겹치지 않는 무작위 숫자 3개를 반환

func InputNumbers() [3]int {
	var rst [3]int
	return rst
} // 키보드로 부터 0~9 사이의 겹치지 않는 숮 3개를 입력받아 반환

func CompareNumbers(numbers, inputNumbers [3]int) bool {
	return true
} // 두개의 숫자 3개를 비교해서 결과를 반환

func PrintResult(result bool) {
	fmt.Println(result)
} // 스트라이크 볼 을 판단하는 결과를 반환

func IsGameEnd(result bool) bool {
	return result
} // 비교 결과가 3스트라이크 인지 확인

--------------------------
true
1번 만에 맞췄습니다.

3.함수 구현 하기

1) 랜덤 숫자 함수

package main

import (
	"fmt"
	"math/rand" // 랜덤 숫자를 위한 패키지 호출
	"time"      //항상 변하는 seed 값을 주기위해 time을 호출
)

func main() {
	rand.Seed(time.Now().UnixNano()) // 랜덤 숫자를 위해 seed값 설정
	numbers := MakeNumbers()         

	cnt := 0

	for {
		cnt++
		inputNumbers := InputNumbers() 

		result := CompareNumbers(numbers, inputNumbers) 

		PrintResult(result)

		if IsGameEnd(result) {
			break
		} 
	}
	fmt.Printf("%d번 만에 맞췄습니다.", cnt)
	
}

func MakeNumbers() [3]int {
	var rst [3]int

	for i := 0; i < 3; i++ {
		for {
			n := rand.Intn(10)
			duplicated := false // 겹치는지 안겹치는지에 대한 플래그 변수 초기값
			for j := 0; j < i; j++ {
				if rst[j] == n { //숫자가 겹친다면 다시 뽑는다.
					duplicated = true //겹치면 true
					break
				}
			}
			if !duplicated { //겹치지 않는다면 for문을 빠져 나간다.
				rst[i] = n
				break
			}
		}
	}

	fmt.Println(rst)
	return rst
} // 0~9 사이의 겹치지 않는 무작위 숫자 3개를 반환

<생략>

--------------------------
[7 9 6]
true
1번 만에 맞췄습니다.

2) 키보드 입력 받기

<생략>

func InputNumbers() [3]int {
	var rst [3]int

	for {
		fmt.Println("겹치지 않는 0~9 사이의 숫자 3개를 입력하세요.")
		var no int
		_, err := fmt.Scanf("%d\n", &no) // scanf 를 통해 값을 입력 받음 \n 를 하여 엔터값까지 입력 받아야함
		// _ 사용하지 않는 변수 , err 에러를 받음
		if err != nil { // 에러가 null이 아닌 경우: 에러가 났을 경우
			fmt.Println("잘못 입력하셨습니다.")
			continue
		}
		success := true
		idx := 0 // rst에 넣을 변수
		for no > 0 {
			n := no % 10 // 숫자를 1자리씩 뽑아냄 123 % 10 = 3
			no = no / 10 // 남은 120 / 10 을 하면 12가 나옴 12가 다시가서 반복

			duplicated := false // 겹치는지 안겹치는지에 대한 플래그 변수 초기값
			for j := 0; j < idx; j++ {
				if rst[j] == n { //숫자가 겹친다면 다시 뽑는다.
					duplicated = true //겹치면 true
					break
				}
			}
			if duplicated { //겹치지 않는다면 for문을 빠져 나간다.
				fmt.Println("숫자가 겹치지 않아야 합니다.")
				success = false
				break
			}

			if idx >= 3 {
				fmt.Println("3개 보다 많은 숫자를 입력하셨습니다.")
				success = false
				break
			}

			rst[idx] = n // rst[0] 부터 들어가기 때문에 순서가 바껴서 입력됨
			idx++
		}
		if success && idx < 3 { //success가 ture고 3보다 idx가 작을때
			fmt.Println("3개의 숫자를 입력하세요.")
			success = false
		}

		if !success { // 숫자가 겹치면 다시 for 문으로 돌아감
			continue
		}
		break // 숫자를 받았으면 for문을 빠져나온다.
	}
	rst[0], rst[2] = rst[2], rst[0] // 순서를 똑바로 돌려줌
	fmt.Println(rst)
	return rst
} // 키보드로 부터 0~9 사이의 겹치지 않는 숮 3개를 입력받아 반환

<생략>
------------------------------------
겹치지 않는 0~9 사이의 숫자 3개를 입력하세요.
123
[1 2 3]
true
1번 만에 맞췄습니다.

3) 숫자 비교하고 결과 출력

<생략>

type Result struct { // 스트라이크와 볼의 구조체
	strikes int
	balls int
}

func CompareNumbers(numbers, inputNumbers [3]int) Result { //Result 구조체를 반환
	strikes := 0 
	balls := 0
	for i := 0; i < 3; i++{ // 첫번째 숫자를 컴퓨터의 3숫자와 비교하고 나머지도 똑같이
		for j := 0; j < 3; j++ {
			if numbers[i] == inputNumbers[j]{
				if i==j { // numbers와 input이 같으면 스트라이크 
					strikes++
				}else{   // 그 외에 볼
					balls++
				}
				break
			}
		}
	}
	return Result{strikes, balls} //구조체를 통해 반환
} // 두개의 숫자 3개를 비교해서 결과를 반환

func PrintResult(result Result) {
	fmt.Printf("%dS%dB\n",result.strikes, result.balls)
} // 스트라이크 볼 을 판단하는 결과를 반환

func IsGameEnd(result Result) bool {

	return result.strikes == 3
} // 비교 결과가 3스트라이크 인지 확인

4) 숫자 야구 완성

package main

import (
	"fmt"
	"math/rand" // 랜덤 숫자를 위한 패키지 호출
	"time"      //항상 변하는 seed 값을 주기위해 time을 호출
)

type Result struct { // 스트라이크와 볼의 구조체
	strikes int
	balls   int
}

func main() {
	rand.Seed(time.Now().UnixNano()) // 랜덤 숫자를 위해 seed값 설정
	numbers := MakeNumbers()         // 무작위 숫자 3개를 만든다.

	cnt := 0

	for {
		cnt++
		inputNumbers := InputNumbers() // 사용자의 입력을 받는다.

		result := CompareNumbers(numbers, inputNumbers) // 결과를 비교한다.

		PrintResult(result)

		if IsGameEnd(result) {
			break
		} // 3S 일경우 게임 끝}
	}
	fmt.Printf("%d번 만에 맞췄습니다.", cnt)
	//몇번만에 맞췄는지 출력
}

func MakeNumbers() [3]int {
	var rst [3]int

	for i := 0; i < 3; i++ {
		for {
			n := rand.Intn(10)
			duplicated := false // 겹치는지 안겹치는지에 대한 플래그 변수 초기값
			for j := 0; j < i; j++ {
				if rst[j] == n { //숫자가 겹친다면 다시 뽑는다.
					duplicated = true //겹치면 true
					break
				}
			}
			if !duplicated { //겹치지 않는다면 for문을 빠져 나간다.
				rst[i] = n
				break
			}
		}
	}

	// fmt.Println(rst)
	return rst
} // 0~9 사이의 겹치지 않는 무작위 숫자 3개를 반환

func InputNumbers() [3]int {
	var rst [3]int

	for {
		fmt.Println("겹치지 않는 0~9 사이의 숫자 3개를 입력하세요.")
		var no int
		_, err := fmt.Scanf("%d\n", &no) // scanf 를 통해 값을 입력 받음 \n 를 하여 엔터값까지 입력 받아야함
		// _ 사용하지 않는 변수 , err 에러를 받음
		if err != nil { // 에러가 null이 아닌 경우: 에러가 났을 경우
			fmt.Println("잘못 입력하셨습니다.")
			continue
		}
		success := true
		idx := 0 // rst에 넣을 변수
		for no > 0 {
			n := no % 10 // 숫자를 1자리씩 뽑아냄 123 % 10 = 3
			no = no / 10 // 남은 120 / 10 을 하면 12가 나옴 12가 다시가서 반복

			duplicated := false // 겹치는지 안겹치는지에 대한 플래그 변수 초기값
			for j := 0; j < idx; j++ {
				if rst[j] == n { //숫자가 겹친다면 다시 뽑는다.
					duplicated = true //겹치면 true
					break
				}
			}
			if duplicated { //겹치지 않는다면 for문을 빠져 나간다.
				fmt.Println("숫자가 겹치지 않아야 합니다.")
				success = false
				break
			}

			if idx >= 3 {
				fmt.Println("3개 보다 많은 숫자를 입력하셨습니다.")
				success = false
				break
			}

			rst[idx] = n // rst[0] 부터 들어가기 때문에 순서가 바껴서 입력됨
			idx++
		}
		if success && idx < 3 { //success가 ture고 3보다 idx가 작을때
			fmt.Println("3개의 숫자를 입력하세요.")
			success = false
		}

		if !success { // 숫자가 겹치면 다시 for 문으로 돌아감
			continue
		}
		break // 숫자를 받았으면 for문을 빠져나온다.
	}
	rst[0], rst[2] = rst[2], rst[0] // 순서를 똑바로 돌려줌
	// fmt.Println(rst)
	return rst
} // 키보드로 부터 0~9 사이의 겹치지 않는 숮 3개를 입력받아 반환

func CompareNumbers(numbers, inputNumbers [3]int) Result { //Result 구조체를 받음
	strikes := 0
	balls := 0
	for i := 0; i < 3; i++ { // 첫번째 숫자를 컴퓨터의 3숫자와 비교하고 나머지도 똑같이
		for j := 0; j < 3; j++ {
			if numbers[i] == inputNumbers[j] {
				if i == j { // numbers와 input이 같으면 스트라이크
					strikes++
				} else { // 그 외에 볼
					balls++
				}
				break
			}
		}
	}
	return Result{strikes, balls} //구조체를 통해 반환
} // 두개의 숫자 3개를 비교해서 결과를 반환

func PrintResult(result Result) {
	fmt.Printf("%dS%dB\n", result.strikes, result.balls)
} // 스트라이크 볼 을 판단하는 결과를 반환

func IsGameEnd(result Result) bool {

	return result.strikes == 3
} // 비교 결과가 3스트라이크 인지 확인

좋은 웹페이지 즐겨찾기