mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 07:10:42 -08:00
Added go version of Fur Trader
This commit is contained in:
326
00_Alternate_Languages/38_Fur_Trader/go/main.go
Normal file
326
00_Alternate_Languages/38_Fur_Trader/go/main.go
Normal file
@@ -0,0 +1,326 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
MAXFURS = 190
|
||||
STARTFUNDS = 600
|
||||
)
|
||||
|
||||
type Fur int8
|
||||
|
||||
const (
|
||||
FUR_MINK Fur = iota
|
||||
FUR_BEAVER
|
||||
FUR_ERMINE
|
||||
FUR_FOX
|
||||
)
|
||||
|
||||
type Fort int8
|
||||
|
||||
const (
|
||||
FORT_MONTREAL Fort = iota
|
||||
FORT_QUEBEC
|
||||
FORT_NEWYORK
|
||||
)
|
||||
|
||||
type GameState int8
|
||||
|
||||
const (
|
||||
STARTING GameState = iota
|
||||
TRADING
|
||||
CHOOSINGFORT
|
||||
TRAVELLING
|
||||
)
|
||||
|
||||
func FURS() []string {
|
||||
return []string{"MINK", "BEAVER", "ERMINE", "FOX"}
|
||||
}
|
||||
|
||||
func FORTS() []string {
|
||||
return []string{"HOCHELAGA (MONTREAL)", "STADACONA (QUEBEC)", "NEW YORK"}
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
funds float32
|
||||
furs []int
|
||||
}
|
||||
|
||||
func NewPlayer() Player {
|
||||
p := Player{}
|
||||
p.funds = STARTFUNDS
|
||||
p.furs = make([]int, 4)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *Player) totalFurs() int {
|
||||
f := 0
|
||||
for _, v := range p.furs {
|
||||
f += v
|
||||
}
|
||||
return f
|
||||
}
|
||||
|
||||
func (p *Player) lostFurs() {
|
||||
for f := 0; f < len(p.furs); f++ {
|
||||
p.furs[f] = 0
|
||||
}
|
||||
}
|
||||
|
||||
func printTitle() {
|
||||
fmt.Println(" FUR TRADER")
|
||||
fmt.Println(" CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
|
||||
fmt.Println()
|
||||
fmt.Println()
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func printIntro() {
|
||||
fmt.Println("YOU ARE THE LEADER OF A FRENCH FUR TRADING EXPEDITION IN ")
|
||||
fmt.Println("1776 LEAVING THE LAKE ONTARIO AREA TO SELL FURS AND GET")
|
||||
fmt.Println("SUPPLIES FOR THE NEXT YEAR. YOU HAVE A CHOICE OF THREE")
|
||||
fmt.Println("FORTS AT WHICH YOU MAY TRADE. THE COST OF SUPPLIES")
|
||||
fmt.Println("AND THE AMOUNT YOU RECEIVE FOR YOUR FURS WILL DEPEND")
|
||||
fmt.Println("ON THE FORT THAT YOU CHOOSE.")
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func getFortChoice() Fort {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
|
||||
for {
|
||||
fmt.Println()
|
||||
fmt.Println("YOU MAY TRADE YOUR FURS AT FORT 1, FORT 2,")
|
||||
fmt.Println("OR FORT 3. FORT 1 IS FORT HOCHELAGA (MONTREAL)")
|
||||
fmt.Println("AND IS UNDER THE PROTECTION OF THE FRENCH ARMY.")
|
||||
fmt.Println("FORT 2 IS FORT STADACONA (QUEBEC) AND IS UNDER THE")
|
||||
fmt.Println("PROTECTION OF THE FRENCH ARMY. HOWEVER, YOU MUST")
|
||||
fmt.Println("MAKE A PORTAGE AND CROSS THE LACHINE RAPIDS.")
|
||||
fmt.Println("FORT 3 IS FORT NEW YORK AND IS UNDER DUTCH CONTROL.")
|
||||
fmt.Println("YOU MUST CROSS THROUGH IROQUOIS LAND.")
|
||||
fmt.Println("ANSWER 1, 2, OR 3.")
|
||||
fmt.Print(">> ")
|
||||
scanner.Scan()
|
||||
|
||||
f, err := strconv.Atoi(scanner.Text())
|
||||
if err != nil || f < 1 || f > 3 {
|
||||
fmt.Println("Invalid input, Try again ... ")
|
||||
continue
|
||||
}
|
||||
return Fort(f)
|
||||
}
|
||||
}
|
||||
|
||||
func printFortComment(f Fort) {
|
||||
fmt.Println()
|
||||
switch f {
|
||||
case FORT_MONTREAL:
|
||||
fmt.Println("YOU HAVE CHOSEN THE EASIEST ROUTE. HOWEVER, THE FORT")
|
||||
fmt.Println("IS FAR FROM ANY SEAPORT. THE VALUE")
|
||||
fmt.Println("YOU RECEIVE FOR YOUR FURS WILL BE LOW AND THE COST")
|
||||
fmt.Println("OF SUPPLIES HIGHER THAN AT FORTS STADACONA OR NEW YORK.")
|
||||
case FORT_QUEBEC:
|
||||
fmt.Println("YOU HAVE CHOSEN A HARD ROUTE. IT IS, IN COMPARSION,")
|
||||
fmt.Println("HARDER THAN THE ROUTE TO HOCHELAGA BUT EASIER THAN")
|
||||
fmt.Println("THE ROUTE TO NEW YORK. YOU WILL RECEIVE AN AVERAGE VALUE")
|
||||
fmt.Println("FOR YOUR FURS AND THE COST OF YOUR SUPPLIES WILL BE AVERAGE.")
|
||||
case FORT_NEWYORK:
|
||||
fmt.Println("YOU HAVE CHOSEN THE MOST DIFFICULT ROUTE. AT")
|
||||
fmt.Println("FORT NEW YORK YOU WILL RECEIVE THE HIGHEST VALUE")
|
||||
fmt.Println("FOR YOUR FURS. THE COST OF YOUR SUPPLIES")
|
||||
fmt.Println("WILL BE LOWER THAN AT ALL THE OTHER FORTS.")
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
func getYesOrNo() string {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for {
|
||||
fmt.Println("ANSWER YES OR NO")
|
||||
scanner.Scan()
|
||||
if strings.ToUpper(scanner.Text())[0:1] == "Y" {
|
||||
return "Y"
|
||||
} else if strings.ToUpper(scanner.Text())[0:1] == "N" {
|
||||
return "N"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getFursPurchase() []int {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
fmt.Printf("YOUR %d FURS ARE DISTRIBUTED AMONG THE FOLLOWING\n", MAXFURS)
|
||||
fmt.Println("KINDS OF PELTS: MINK, BEAVER, ERMINE AND FOX.")
|
||||
fmt.Println()
|
||||
|
||||
purchases := make([]int, 4)
|
||||
|
||||
for i, f := range FURS() {
|
||||
retry:
|
||||
fmt.Printf("HOW MANY %s DO YOU HAVE: ", f)
|
||||
scanner.Scan()
|
||||
count, err := strconv.Atoi(scanner.Text())
|
||||
if err != nil {
|
||||
fmt.Println("INVALID INPUT, TRY AGAIN ...")
|
||||
goto retry
|
||||
}
|
||||
purchases[i] = count
|
||||
}
|
||||
|
||||
return purchases
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
printTitle()
|
||||
|
||||
gameState := STARTING
|
||||
whichFort := FORT_NEWYORK
|
||||
var (
|
||||
minkPrice int
|
||||
erminePrice int
|
||||
beaverPrice int
|
||||
foxPrice int
|
||||
)
|
||||
player := NewPlayer()
|
||||
|
||||
for {
|
||||
switch gameState {
|
||||
case STARTING:
|
||||
printIntro()
|
||||
fmt.Println("DO YOU WISH TO TRADE FURS?")
|
||||
if getYesOrNo() == "N" {
|
||||
os.Exit(0)
|
||||
}
|
||||
gameState = TRADING
|
||||
case TRADING:
|
||||
fmt.Println()
|
||||
fmt.Printf("YOU HAVE $ %1.2f IN SAVINGS\n", player.funds)
|
||||
fmt.Printf("AND %d FURS TO BEGIN THE EXPEDITION\n", MAXFURS)
|
||||
player.furs = getFursPurchase()
|
||||
|
||||
if player.totalFurs() > MAXFURS {
|
||||
fmt.Println()
|
||||
fmt.Println("YOU MAY NOT HAVE THAT MANY FURS.")
|
||||
fmt.Println("DO NOT TRY TO CHEAT. I CAN ADD.")
|
||||
fmt.Println("YOU MUST START AGAIN.")
|
||||
gameState = STARTING
|
||||
} else {
|
||||
gameState = CHOOSINGFORT
|
||||
}
|
||||
case CHOOSINGFORT:
|
||||
whichFort = getFortChoice()
|
||||
printFortComment(whichFort)
|
||||
fmt.Println("DO YOU WANT TO TRADE AT ANOTHER FORT?")
|
||||
changeFort := getYesOrNo()
|
||||
if changeFort == "N" {
|
||||
gameState = TRAVELLING
|
||||
}
|
||||
case TRAVELLING:
|
||||
switch whichFort {
|
||||
case FORT_MONTREAL:
|
||||
minkPrice = (int((0.2*rand.Float64()+0.70)*100+0.5) / 100)
|
||||
erminePrice = (int((0.2*rand.Float64()+0.65)*100+0.5) / 100)
|
||||
beaverPrice = (int((0.2*rand.Float64()+0.75)*100+0.5) / 100)
|
||||
foxPrice = (int((0.2*rand.Float64()+0.80)*100+0.5) / 100)
|
||||
|
||||
fmt.Println("SUPPLIES AT FORT HOCHELAGA COST $150.00.")
|
||||
fmt.Println("YOUR TRAVEL EXPENSES TO HOCHELAGA WERE $10.00.")
|
||||
player.funds -= 160
|
||||
case FORT_QUEBEC:
|
||||
minkPrice = (int((0.30*rand.Float64()+0.85)*100+0.5) / 100)
|
||||
erminePrice = (int((0.15*rand.Float64()+0.80)*100+0.5) / 100)
|
||||
beaverPrice = (int((0.20*rand.Float64()+0.90)*100+0.5) / 100)
|
||||
foxPrice = (int((0.25*rand.Float64()+1.10)*100+0.5) / 100)
|
||||
|
||||
event := int(10*rand.Float64()) + 1
|
||||
if event <= 2 {
|
||||
fmt.Println("YOUR BEAVER WERE TOO HEAVY TO CARRY ACROSS")
|
||||
fmt.Println("THE PORTAGE. YOU HAD TO LEAVE THE PELTS, BUT FOUND")
|
||||
fmt.Println("THEM STOLEN WHEN YOU RETURNED.")
|
||||
player.furs[FUR_BEAVER] = 0
|
||||
} else if event <= 6 {
|
||||
fmt.Println("YOU ARRIVED SAFELY AT FORT STADACONA.")
|
||||
} else if event <= 8 {
|
||||
fmt.Println("YOUR CANOE UPSET IN THE LACHINE RAPIDS. YOU")
|
||||
fmt.Println("LOST ALL YOUR FURS.")
|
||||
player.lostFurs()
|
||||
} else if event <= 10 {
|
||||
fmt.Println("YOUR FOX PELTS WERE NOT CURED PROPERLY.")
|
||||
fmt.Println("NO ONE WILL BUY THEM.")
|
||||
player.furs[FUR_FOX] = 0
|
||||
} else {
|
||||
log.Fatal("Unexpected error")
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("SUPPLIES AT FORT STADACONA COST $125.00.")
|
||||
fmt.Println("YOUR TRAVEL EXPENSES TO STADACONA WERE $15.00.")
|
||||
player.funds -= 140
|
||||
case FORT_NEWYORK:
|
||||
minkPrice = (int((0.15*rand.Float64()+1.05)*100+0.5) / 100)
|
||||
erminePrice = (int((0.15*rand.Float64()+0.95)*100+0.5) / 100)
|
||||
beaverPrice = (int((0.25*rand.Float64()+1.00)*100+0.5) / 100)
|
||||
foxPrice = (int((0.25*rand.Float64()+1.05)*100+0.5) / 100) // not in original code
|
||||
|
||||
event := int(10*rand.Float64()) + 1
|
||||
if event <= 2 {
|
||||
fmt.Println("YOU WERE ATTACKED BY A PARTY OF IROQUOIS.")
|
||||
fmt.Println("ALL PEOPLE IN YOUR TRADING GROUP WERE")
|
||||
fmt.Println("KILLED. THIS ENDS THE GAME.")
|
||||
os.Exit(0)
|
||||
} else if event <= 6 {
|
||||
fmt.Println("YOU WERE LUCKY. YOU ARRIVED SAFELY")
|
||||
fmt.Println("AT FORT NEW YORK.")
|
||||
} else if event <= 8 {
|
||||
fmt.Println("YOU NARROWLY ESCAPED AN IROQUOIS RAIDING PARTY.")
|
||||
fmt.Println("HOWEVER, YOU HAD TO LEAVE ALL YOUR FURS BEHIND.")
|
||||
player.lostFurs()
|
||||
} else if event <= 10 {
|
||||
minkPrice /= 2
|
||||
foxPrice /= 2
|
||||
fmt.Println("YOUR MINK AND BEAVER WERE DAMAGED ON YOUR TRIP.")
|
||||
fmt.Println("YOU RECEIVE ONLY HALF THE CURRENT PRICE FOR THESE FURS.")
|
||||
} else {
|
||||
log.Fatal("Unexpected error")
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
fmt.Println("SUPPLIES AT NEW YORK COST $85.00.")
|
||||
fmt.Println("YOUR TRAVEL EXPENSES TO NEW YORK WERE $25.00.")
|
||||
player.funds -= 110
|
||||
}
|
||||
|
||||
beaverValue := beaverPrice * player.furs[FUR_BEAVER]
|
||||
foxValue := foxPrice * player.furs[FUR_FOX]
|
||||
ermineValue := erminePrice * player.furs[FUR_ERMINE]
|
||||
minkValue := minkPrice * player.furs[FUR_MINK]
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf("YOUR BEAVER SOLD FOR $%6.2f\n", float64(beaverValue))
|
||||
fmt.Printf("YOUR FOX SOLD FOR $%6.2f\n", float64(foxValue))
|
||||
fmt.Printf("YOUR ERMINE SOLD FOR $%6.2f\n", float64(ermineValue))
|
||||
fmt.Printf("YOUR MINK SOLD FOR $%6.2f\n", float64(minkValue))
|
||||
|
||||
player.funds += float32(beaverValue + foxValue + ermineValue + minkValue)
|
||||
|
||||
fmt.Println()
|
||||
fmt.Printf("YOU NOW HAVE $%1.2f INCLUDING YOUR PREVIOUS SAVINGS\n", player.funds)
|
||||
fmt.Println("\nDO YOU WANT TO TRADE FURS NEXT YEAR?")
|
||||
if getYesOrNo() == "N" {
|
||||
os.Exit(0)
|
||||
} else {
|
||||
gameState = TRADING
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user