Golang - 숫자 맞추기 게임 [ 예제 ], 시간

Lumi·2022년 2월 9일
0

Golang

목록 보기
10/38
post-thumbnail

🔥 개요 및 코드 설명

기본적으로 math/rand를 통해서 랜덤한 숫자를 만들어 줍니다.

이후 사용자 입력을 통해서 값을 받고

어떠한 값이 큰지를 비교를 함으로써 작동을 합니다.

  • 만약 입력한 값이 작으면 다시 입력을 받고
  • 크면 성공했다는 출력과 함께 게임이 종료 됩니다.

굉장히 단순한 게임입니다.. ㅎ

rand.Seed, rand.Intn

package main

import (
	"fmt"
	"math/rand"
)

func main() {
	rand.Seed(100)
	for i := 0; i < 10; i++ {
		fmt.Println(rand.Intn((100)))
	}
}

랜덤한 값을 만드는 함수 입니다.

math/rand패키지를 통해서 사용이 가능하며

이런식으로 고정적인 값을 인자로 넘기게 되면
처음에만 랜덤한 값이 나오지 이후에는 동일한 값이 나옵니다.

예를들면

a b c 라는 값이 처음에 랜덤하게 나왔으면

이후에도 동일한 인자로 작동을 하면 

a b c 라는 값만 나오게 됩니다.

즉 저희는 랜덤한 값을 나오기 위해서는 계속 변화하는 값이 필요하고 이러한 값에 적합한 인자는 바로 시간입니다.

  • 현재 시간은 계속해서 변하기 떄문에
  • time.Now()를 사용

하지만 rand.Intn에 들어가는 인자는 int64이며 time.Now()의 반환값은 Time구조체 타입이기 떄문에 변화시켜줄 필요가 있습니다.

이 부분은 굉장히 간단합니다.

그냥 내부함수를 통해서 수정이 가능하며 UnixNano()를 적용시키면 int64타입으로 반환이 가능합니다.

package main

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

func main() {
	t := time.Now()
	rand.Seed(t.UnixNano())
	for i := 0; i < 10; i++ {
		fmt.Println(rand.Intn((100)))
	}
}
  • 즉 실행할떄마다 현재의 시간이 계속 바뀐다는 부분을 활용한 난수 생성 코드라고 할수 있습니다.

전체 코드

package main

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

func main() {
	t := time.Now()
	rand.Seed(t.UnixNano())

	for {
		var number int64
		var rand_number = int64(rand.Intn(10))
		fmt.Println("숫자를 입력해 주세요!")
		_, err := fmt.Scanln(&number)
		if err == nil {
			if number > rand_number {
				fmt.Printf("승리하였습니다!!! 랜덤한 값은 %d 입니다.\n", rand_number)
				break
			} else {
				fmt.Println("실패!!! 다시 게임을 시작합니다!\n")
			}
		}

	}

}

사실 코드적으로 그렇게 어려운 방법은 아니라서;;; 마땅히 어떠한 설명을 해야 할지를 모르겠습니다.

이전까지의 코드에 대한 간략한 설명을 했었기 떄문에 단순히 랜덤한 값을 부여함으로써 값을 도출해내고 비교를 하는 작업을 진행하였습니다.

🔥 시간

간단한 예제를 진행하였지만 공부를 하면서 시간이라는 부분에 대해서 많은 호기심이 생기게 되었습니다.

시간이라는 개념은 블록체인에서도 상당히 중요한 부분입니다.

오늘 면접볼떄에도 답변하지 못하고 많은 부분을 배웠던 부분중 하나였고 잠시 다른 이야기좀 하자면

블록체인에서 악의적인 사용자가 시간을 기록하는 것을 어떻게 방지를 할까요??
- 라는 질문이 있었습니다;;

당시에는 저로써는 생각하지도 못하였던 문제기 떄문에 그냥 단순하게 블록이 채굴되는 시간에 따라서 블록에 기록이 되지 않을까?? 라는 답변을 하였습니다.
- 이더를 예로 들면 15초

하지만 생각보다 굉장히 심오했습니다.

왜냐하면 악의적인 사용자라면 그냥 임의로 시간을 바꿔서 설정할수 있는 상황이 발생가능하기 떄문입니다.

이러한 부분을 막기 위해서 블록체인에서는 이전의 블록에 기록된 시간 간격의 평균값을 활용하여 비교를 한다고 합니다.
- 정말 새롭게 알게된 사실입니다!! 좋은 결과가 나올꺼라 생각은 하지 않지만 많은 부분을 배웠던 시간인거 같습니다.

이처럼 블록체인에서도 시간이라는 상대적개념은 상당히 중요하고 Golang을 포함하여 언어에서 아니 프로그램적인 부분에서 시간이라는 개념은 상당히 중요한 요인입니다.

그러기 떄문에 예제적인 부분을 빠르게 끝내고 시간에 대하여 공부를 해 보았습니다.

Time패키지에는 정말 많은 함수가 있습니다.

또한 golang에서는 정말 많은 형식의 Time형태를 제공합니다.

  ANSIC       = "Mon Jan _2 15:04:05 2006"
        UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
        RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
        RFC822      = "02 Jan 06 15:04 MST"
        RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
        RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
        RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
        RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
        RFC3339     = "2006-01-02T15:04:05Z07:00"
        RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
        Kitchen     = "3:04PM"
        // Handy time stamps.
        Stamp      = "Jan _2 15:04:05"
        StampMilli = "Jan _2 15:04:05.000"
        StampMicro = "Jan _2 15:04:05.000000"
        StampNano  = "Jan _2 15:04:05.000000000"
  • 이런 느낌;;

이 모든 것들을 활용할수는 없고 흔히 사용되는 방식은
yyyy-mm-dd hh:mm:ss방식입니다.

현재 시간 확인하기

package main

import (
	"fmt"
	"time"
)

func main() {
	now := time.Now()
	custom := now.Format("2006-01-02 15:04:05")
	ansic := now.Format(time.ANSIC)
	fmt.Println(custom)
	fmt.Println(ansic)
}

저희에게 좀더 익숙한 방법으로 현재의 시간을 확인하는 방법입니다.

현재시간에서 시간 뺴기 [시, 분]

	now := time.Now()

	convMinutes, _ := time.ParseDuration("10m")
	convHours, _ := time.ParseDuration("1h")

	diffMinutes := now.Add(-convMinutes).Format(time.ANSIC)
	diffHours := now.Add(-convHours).Format(time.ANSIC)

	fmt.Println(diffMinutes)
	fmt.Println(diffHours)
  • time.ParseDuration을 활용하여 시간을 조율이 가능합니다.

함수종류와 타입 부분만 알면 원활하게 진행이 될꺼 같은데;; 이 부분이 가장 어려운거 같습니다.

현재시간에서 시간 뺴기 [년, 월, 일]

	now := time.Now()

	convDays := 1
	convMonths := 1
	convYears := 1

	diffDays := now.AddDate(0, 0, -convDays).Format(time.ANSIC)
	diffMonths := now.AddDate(0, -convMonths, 0).Format(time.ANSIC)
	diffYears := now.AddDate(-convYears, 0, 0).Format(time.ANSIC)

	fmt.Println(now)
	fmt.Println(diffDays)
	fmt.Println(diffMonths)
	fmt.Println(diffYears)
  • 함수의 종류만 AddDate로 수정함으로써 년, 월, 일 부분까지 수정이 가능합니다.
profile
[기술 블로그가 아닌 하루하루 기록용 블로그]

0개의 댓글