Search

마일리지 상점 구현

Created
2021/03/23 01:58
Tags
package main import ( "fmt" "time" ) type item struct { name string price int amount int } type buyer struct { point int cart map[string]int } type delivery struct { status string products map[string]int } func newBuyer() *buyer { tmp := new(buyer) tmp.point = 1000000 tmp.cart = make(map[string]int ,0) return tmp } func (b *buyer) buyItems(items []item, limits *int, d chan bool, tmpProd map[string]int) { defer func() { if r := recover(); r != nil { fmt.Println(r) fmt.Println() b.buyItems(items, limits, d, tmpProd) } }() module := func (idx int) { amount := 0 fmt.Print("수량을 입력하시오 : ") fmt.Scanln(&amount) fmt.Println() if amount <= 0 { panic("올바른 수량을 입력하세요.") } if b.point < items[idx].price * amount || items[idx].amount < amount { panic("주문이 불가능합니다.") } else { for { opt := 0 fmt.Println("1. 바로 주문\n2. 장바구니에 담기") fmt.Print("실행할 기능을 입력하시오 : ") fmt.Scanln(&opt) fmt.Println() if opt == 1 { if *limits < 5 { items[idx].amount -= amount b.point -= items[idx].price * amount tmpProd[items[idx].name] = amount fmt.Println("상품 주문이 접수 되었습니다.") *limits++ d <- true break } else { fmt.Println("배송 한도를 초과했습니다. 배송이 완료되면 주문하세요.") break } } else if opt == 2 { already := false for key := range b.cart { if key == items[idx].name { already = true break } } if already { tmp := b.cart[items[idx].name] + amount if tmp > items[idx].amount { fmt.Println("물품의 잔여 수량을 초과했습니다.") break } else { b.cart[items[idx].name] += amount } } else { b.cart[items[idx].name] = amount } fmt.Println("상품이 장바구니에 추가 되었습니다.") break } else { fmt.Println("잘못된 입력입니다. 다시 입력해주세요.\n") } } } } for { choice := 0 checkShop(items) fmt.Print("구매할 물품을 선택하세요 : ") fmt.Scanln(&choice) fmt.Println() if choice >= 1 && choice <= 5 { module(choice - 1) break } else { fmt.Println("잘못된 입력입니다. 다시 입력해주세요.\n") } } } func (b *buyer) checkPoint() { fmt.Printf("현재 잔여 마일리지는 %d점입니다.\n", b.point) } func (b *buyer) checkCart(items []item, limits *int, d chan bool, tmpProd map[string]int) { pointModule := func () (afford bool) { cartTotal := 0 for key, val := range b.cart { for i := 0; i < len(items); i++ { if items[i].name == key { cartTotal += items[i].price * val } } } fmt.Println("필요 마일리지 : ", cartTotal) fmt.Println("보유 마일리지 : ", b.point) fmt.Println() if b.point < cartTotal { fmt.Printf("마일리지가 %d점 부족합니다.\n", cartTotal - b.point) fmt.Println() return false } return true } amountModule := func() (afford bool) { for key, val := range b.cart { for i := 0; i < len(items); i++ { if items[i].name == key { if items[i].amount < val { fmt.Printf("%s, 잔여 수량에서 %d개 초과", items[i].name, val - items[i].amount) return false } } } } return true } payModule := func() { defer func() { if r:= recover(); r != nil { fmt.Println(r) } }() if len(b.cart) == 0 { panic("주문 가능한 목록이 없습니다.") } else { if (*limits < 5) { for key, val := range b.cart { tmpProd[key] = val for i := range items { if items[i].name == key { items[i].amount -= val b.point -= items[i].price * val } } } b.cart = make(map[string]int, 0) fmt.Println("주문이 접수 되었습니다.") *limits++ d <- true } else { fmt.Println("배송 한도를 초과했습니다. 배송이 완료되면 주문하세요.") } } } for { if len(b.cart) == 0 { fmt.Println("장바구니가 비었습니다.\n") } else { for key, val := range b.cart { fmt.Printf("%s, 수량 : %d\n", key, val) } } opt := 0 fmt.Println("1. 장바구니 상품 주문") fmt.Println("2. 장바구니 초기화") fmt.Println("3. 메뉴로 돌아가기") fmt.Print("실행할 기능을 입력하시오 : ") fmt.Scanln(&opt) fmt.Println() if opt == 1 { pointAfford := pointModule() amountAfford := amountModule() if pointAfford && amountAfford { payModule() break } else { fmt.Println("구매할 수 없습니다.") break } } else if opt == 2 { b.cart = make(map[string]int, 0) fmt.Println("장바구니를 초기화했습니다.") break } else if opt == 3 { break } else { fmt.Println("잘못된 입력입니다. 다시 입력해주세요.") } } } func newDelivery() delivery { tmp := delivery{} tmp.products = make(map[string]int, 0) return tmp } func initDelivery(list []delivery) { for i := range list { list[i] = newDelivery() } } func initShop(items []item) { items[0] = item{"텀블러", 10000, 30} items[1] = item{"롱패딩", 500000, 20} items[2] = item{"투미 백팩", 400000, 20} items[3] = item{"나이키 운동화", 150000, 50} items[4] = item{"빼빼로", 1200, 500} } func checkShop(items []item) { for idx, i := range items { fmt.Printf("물품 %d : %s, 가격 : %d, 잔여 수량 : %d\n", idx + 1, i.name, i.price, i.amount) } fmt.Println() } func checkDeliveryStatus(list []delivery) { total := 0 for i := 0; i < 5; i++ { total += len(list[i].products) } if total == 0 { fmt.Println("배송 중인 상품이 없습니다.") } else { for i := range list { if len(list[i].products) != 0 { for key, val := range list[i].products { fmt.Printf("%s %d개\n", key, val) } } fmt.Printf("배송상황: %s\n", list[i].status) } fmt.Println() } } func deliveryStatus(idx int, list []delivery, limits *int, d chan bool, tmpProd *map[string]int) { for { if <- d { for key, val := range *tmpProd { list[idx].products[key] = val } *tmpProd = make(map[string]int, 0) list[idx].status = "주문접수" time.Sleep(time.Second * 10) list[idx].status = "배송 중" time.Sleep(time.Second * 10) list[idx].status = "배송 완료" time.Sleep(time.Second * 10) list[idx].status = "" list[idx].products = make(map[string]int, 0) *limits-- } } } func main() { jseo := newBuyer() items := make([]item, 5) initShop(items) deliveryList := make([]delivery, 5) initDelivery(deliveryList) limits := 0 dch := make(chan bool) tmpProd := make(map[string]int, 0) for i := 0; i < 5; i++ { time.Sleep(time.Millisecond) go deliveryStatus(i, deliveryList, &limits, dch, &tmpProd) } for { menu := 0 fmt.Println("1. 구매") fmt.Println("2. 잔여 수량 확인") fmt.Println("3. 잔여 마일리지 확인") fmt.Println("4. 배송 상태 확인") fmt.Println("5. 장바구니 확인") fmt.Println("6. 프로그램 종료") fmt.Print("실행할 기능을 입력하시오 : ") fmt.Scanln(&menu) fmt.Println() switch menu { case 1: jseo.buyItems(items, &limits, dch, tmpProd) fmt.Println("엔터를 입력하면 메뉴 화면으로 돌아갑니다.") fmt.Scanln() case 2: checkShop(items) fmt.Println("엔터를 입력하면 메뉴 화면으로 돌아갑니다.") fmt.Scanln() case 3: jseo.checkPoint() fmt.Println("엔터를 입력하면 메뉴 화면으로 돌아갑니다.") fmt.Scanln() case 4: checkDeliveryStatus(deliveryList) fmt.Println("엔터를 입력하면 메뉴 화면으로 돌아갑니다.") fmt.Scanln() case 5: jseo.checkCart(items, &limits, dch, tmpProd) fmt.Println("엔터를 입력하면 메뉴 화면으로 돌아갑니다.") fmt.Scanln() case 6: fmt.Println("프로그램을 종료합니다.") return default: fmt.Println("잘못된 입력입니다. 다시 입력해주세요.\n") } } }
Go