|
@@ -40,54 +40,41 @@ func StringToANSIColor(colorCode string) string {
|
|
|
}
|
|
|
|
|
|
type PlayCards struct {
|
|
|
- Door *door.Door
|
|
|
- DB *DBData
|
|
|
- Config *map[string]string
|
|
|
- RNG *rand.Rand
|
|
|
- Seeds []int32
|
|
|
- Total_hands int
|
|
|
- Play_card int
|
|
|
- Current_streak int
|
|
|
- Best_streak int
|
|
|
- Select_card int
|
|
|
- Score int
|
|
|
- Play_day time.Time
|
|
|
- Play_day_t int64
|
|
|
- Days_played int
|
|
|
- Hand int
|
|
|
- Day_status [42]int
|
|
|
- SpaceAceTriPeaks door.Panel
|
|
|
- ScorePanel door.Panel
|
|
|
- StreakPanel door.Panel
|
|
|
- LeftPanel door.Panel
|
|
|
- CmdPanel door.Panel
|
|
|
- NextQuitPanel door.Panel
|
|
|
- CalendarPanel door.Panel
|
|
|
- DeckPanel Deck
|
|
|
- Deck []DeckType
|
|
|
- State []DeckType
|
|
|
- Off_X int
|
|
|
- Off_Y int
|
|
|
- Calendar_day_t [31]int64
|
|
|
- Calendar door.Screen
|
|
|
+ Door *door.Door
|
|
|
+ DB *DBData
|
|
|
+ Config *map[string]string
|
|
|
+ RNG *rand.Rand
|
|
|
+ Seeds []int32
|
|
|
+ Total_hands int
|
|
|
+ Play_card int
|
|
|
+ Current_streak int
|
|
|
+ Best_streak int
|
|
|
+ Select_card int
|
|
|
+ Score int
|
|
|
+ Play_day time.Time
|
|
|
+ Play_day_t int64
|
|
|
+ Days_played int
|
|
|
+ Hand int
|
|
|
+ SpaceAceTriPeaks door.Panel
|
|
|
+ ScorePanel door.Panel
|
|
|
+ StreakPanel door.Panel
|
|
|
+ LeftPanel door.Panel
|
|
|
+ CmdPanel door.Panel
|
|
|
+ NextQuitPanel door.Panel
|
|
|
+ DeckPanel Deck
|
|
|
+ Deck []DeckType // [51]DeckType t
|
|
|
+ State []DeckType // [51]DeckType
|
|
|
+ Off_X int
|
|
|
+ Off_Y int
|
|
|
+ Calendar_day_t [31]int64
|
|
|
+ Calendar door.Screen
|
|
|
+ Calendar_panel_days [42]int // Where is each day positioned on the Calendar?
|
|
|
+ Calendar_day_status [31]int
|
|
|
}
|
|
|
|
|
|
-// Adjust date to 2:00 AM
|
|
|
-func NormalizeDate(date *time.Time) {
|
|
|
- offset := time.Duration(date.Second())*time.Second +
|
|
|
- time.Duration(date.Minute())*time.Minute +
|
|
|
- time.Duration(date.Hour()-2)*time.Hour +
|
|
|
- time.Duration(date.Nanosecond())*time.Nanosecond
|
|
|
- *date = date.Add(-offset)
|
|
|
-}
|
|
|
-
|
|
|
-// Find the 1st of the Month (Normalized) 2:00 AM
|
|
|
-func FirstOfMonthDate(date *time.Time) {
|
|
|
- if date.Day() != 1 {
|
|
|
- *date = date.AddDate(0, 0, 1-date.Day())
|
|
|
- }
|
|
|
- NormalizeDate(date)
|
|
|
-}
|
|
|
+// Possibly change Deck to [51]DeckType. This game always only has 1 deck.
|
|
|
+// Possibly change State [51]DeckType to [51]int8.
|
|
|
+// There are few states to track.
|
|
|
|
|
|
func cmdLineRender(bracket string, inner string, outer string) func(string) string {
|
|
|
return func(input string) string {
|
|
@@ -333,14 +320,114 @@ func (pc *PlayCards) Init() {
|
|
|
{
|
|
|
pc.Calendar = door.Screen{}
|
|
|
var month time.Time = time.Now()
|
|
|
+ var today_day int = month.Day()
|
|
|
FirstOfMonthDate(&month)
|
|
|
|
|
|
- }
|
|
|
- /*
|
|
|
- // This is make_calendar_panel (not make_calendar)
|
|
|
+ // clear out
|
|
|
+ for x := range pc.Calendar_day_t {
|
|
|
+ pc.Calendar_day_t[x] = 0
|
|
|
+ }
|
|
|
+ // pc.Calendar_day_t = make([]int64, 31)
|
|
|
+ pc.Calendar_day_t[0] = month.Unix()
|
|
|
+ var First_Weekday int = int(month.Weekday())
|
|
|
+ var month_last_day = 0
|
|
|
+ var month_end time.Time = month
|
|
|
+ for {
|
|
|
+ month_end = month_end.AddDate(0, 0, 1)
|
|
|
+ NormalizeDate(&month_end)
|
|
|
+ if month_end.Day() == 1 {
|
|
|
+ break
|
|
|
+ } else {
|
|
|
+ pc.Calendar_day_t[month_end.Day()-1] = month_end.Unix()
|
|
|
+ month_last_day = month_end.Day()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // clear out
|
|
|
+ for x := range pc.Calendar_panel_days {
|
|
|
+ pc.Calendar_panel_days[x] = 0
|
|
|
+ }
|
|
|
+ // pc.Calendar_panel_days = make([]int, 6*7)
|
|
|
+ var row int = 0
|
|
|
+ for x := 0; x < month_last_day; x++ {
|
|
|
+ var dow int = (x + First_Weekday) % 7
|
|
|
+ if x != 0 && dow == 0 {
|
|
|
+ row++
|
|
|
+ }
|
|
|
+ pc.Calendar_panel_days[row*7+dow] = x + 1
|
|
|
+ }
|
|
|
+
|
|
|
+ // clear out
|
|
|
+ for x := range pc.Calendar_day_status {
|
|
|
+ pc.Calendar_day_status[x] = 0
|
|
|
+ }
|
|
|
+ // pc.Calendar_day_status = make([]int, 31)
|
|
|
+ last_played := pc.DB.WhenPlayed()
|
|
|
+
|
|
|
+ for played, hands := range last_played {
|
|
|
+ if played >= month.Unix() {
|
|
|
+ // Ok, it is within the range
|
|
|
+ var played_day int = time.Unix(played, 0).Day()
|
|
|
+ if hands < pc.Total_hands {
|
|
|
+ pc.Calendar_day_status[played_day-1] = 1
|
|
|
+ } else {
|
|
|
+ pc.Calendar_day_status[played_day-1] = 2
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get play_days_ahead from config
|
|
|
+ var play_days_ahead int = 0
|
|
|
+ if playdays, has := (*pc.Config)["play_days_ahead"]; has {
|
|
|
+ play_days_ahead, _ = strconv.Atoi(playdays)
|
|
|
+ }
|
|
|
+
|
|
|
+ // Mark all days ahead as NNY.
|
|
|
+ for d := 0; d < 31; d++ {
|
|
|
+ if today_day+play_days_ahead-1 < d {
|
|
|
+ pc.Calendar_day_status[d] = 3
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get current month as string
|
|
|
+ var current string = strings.ToUpper(CurrentMonth(month))
|
|
|
+ if len(current) < 6 {
|
|
|
+ current = " " + current + " "
|
|
|
+ }
|
|
|
+
|
|
|
+ // FUTURE: Replace this with TDF rendering of Month.
|
|
|
+
|
|
|
+ // make_month
|
|
|
+ var MonthPanel door.Panel = door.Panel{X: 3,
|
|
|
+ Y: 3,
|
|
|
+ Width: 3,
|
|
|
+ Style: door.DOUBLE,
|
|
|
+ BorderColor: door.ColorText("BOLD YELLOW ON BLACK"),
|
|
|
+ }
|
|
|
+ for _, c := range current {
|
|
|
+ MonthPanel.Lines = append(MonthPanel.Lines,
|
|
|
+ door.Line{Text: fmt.Sprintf(" %c ", c)})
|
|
|
+ }
|
|
|
+ pc.Calendar.AddPanel(MonthPanel)
|
|
|
+
|
|
|
+ // make_weekday
|
|
|
+ var WeekdayPanel door.Panel = door.Panel{X: 8,
|
|
|
+ Y: 3,
|
|
|
+ Width: 41,
|
|
|
+ Style: door.DOUBLE,
|
|
|
+ BorderColor: door.ColorText("BOLD CYAN ON BLACK"),
|
|
|
+ }
|
|
|
+ WeekdayPanel.Lines = append(WeekdayPanel.Lines,
|
|
|
+ door.Line{Text: " SUN MON TUE WED THU FRI SAT "})
|
|
|
+ pc.Calendar.AddPanel(WeekdayPanel)
|
|
|
+
|
|
|
+ // make_calendar_panel
|
|
|
+
|
|
|
+ var CalendarPanel door.Panel
|
|
|
+
|
|
|
{
|
|
|
W := 41
|
|
|
- pc.CalendarPanel = door.Panel{Width: W,
|
|
|
+ CalendarPanel = door.Panel{Width: W,
|
|
|
Style: door.DOUBLE,
|
|
|
BorderColor: door.ColorText("CYAN ON BLACK")}
|
|
|
|
|
@@ -363,7 +450,8 @@ func (pc *PlayCards) Init() {
|
|
|
result.Append(spaces, 1)
|
|
|
}
|
|
|
dayText = text[1+days*6 : (1+days*6)+3]
|
|
|
- if dayText[1] == ' ' {
|
|
|
+ // if dayText[1] == ' ' {
|
|
|
+ if dayText[0] == ' ' {
|
|
|
result.Append(spaces, 3)
|
|
|
} else {
|
|
|
// Something is here
|
|
@@ -396,17 +484,20 @@ func (pc *PlayCards) Init() {
|
|
|
}
|
|
|
|
|
|
for row := 0; row < 6; row++ {
|
|
|
+ // Do this, or it doesn't get captured correctly.
|
|
|
+ _row := row
|
|
|
+ // _pc := pc
|
|
|
calendarUpdate := func() string {
|
|
|
var text string
|
|
|
|
|
|
for d := 0; d < 7; d++ {
|
|
|
text += " "
|
|
|
- v := pc.Day_status[(row*7)+d]
|
|
|
+ v := pc.Calendar_panel_days[(_row*7)+d]
|
|
|
if v == 0 {
|
|
|
text += " "
|
|
|
} else {
|
|
|
text += fmt.Sprintf("%-2d", v)
|
|
|
- status := pc.Day_status[v-1]
|
|
|
+ status := pc.Calendar_day_status[v-1]
|
|
|
switch status {
|
|
|
case 0:
|
|
|
text += "o"
|
|
@@ -427,17 +518,25 @@ func (pc *PlayCards) Init() {
|
|
|
return text
|
|
|
}
|
|
|
|
|
|
- pc.Calendar.Lines = append(pc.Calendar.Lines,
|
|
|
+ log.Printf("line %d: [%s]\n", row, calendarUpdate())
|
|
|
+
|
|
|
+ CalendarPanel.Lines = append(CalendarPanel.Lines,
|
|
|
door.Line{Text: calendarUpdate(),
|
|
|
UpdateF: calendarUpdate,
|
|
|
RenderF: calendarRender})
|
|
|
}
|
|
|
}
|
|
|
- */
|
|
|
+ CalendarPanel.X = 8
|
|
|
+ CalendarPanel.Y = 6
|
|
|
+
|
|
|
+ pc.Calendar.AddPanel(CalendarPanel)
|
|
|
+
|
|
|
+ }
|
|
|
+ // end make_calendar
|
|
|
|
|
|
}
|
|
|
|
|
|
-func (pc *PlayCards) Play() {
|
|
|
+func (pc *PlayCards) Play() int {
|
|
|
// this defaults (for now) to playing today (if unplayed).
|
|
|
// Otherwise display calendar.
|
|
|
pc.Play_day = time.Now()
|
|
@@ -446,44 +545,125 @@ func (pc *PlayCards) Play() {
|
|
|
pc.Play_day_t = pc.Play_day.Unix()
|
|
|
played := pc.DB.HandsPlayedOnDay(pc.Play_day_t)
|
|
|
|
|
|
+ log.Printf("HandsPlayedOnDay(%d), %d", pc.Play_day_t, played)
|
|
|
var r int
|
|
|
|
|
|
if played == 0 {
|
|
|
- pc.Door.Write("Let's play today..." + door.CRNL)
|
|
|
- time.Sleep(time.Second)
|
|
|
+ pc.Door.Write(door.CRNL + door.Reset + "Let's play today..." + door.CRNL)
|
|
|
+ time.Sleep(time.Second * time.Duration(2))
|
|
|
pc.Hand = 1
|
|
|
r = pc.PlayCards()
|
|
|
if r != 'D' {
|
|
|
- return
|
|
|
+ return r
|
|
|
}
|
|
|
} else {
|
|
|
if played < pc.Total_hands {
|
|
|
// let's finish today...
|
|
|
+ pc.Door.Write(door.CRNL + door.Reset + "Let's finish today..." + door.CRNL)
|
|
|
+ time.Sleep(time.Second * time.Duration(2))
|
|
|
pc.Hand = played + 1
|
|
|
r = pc.PlayCards()
|
|
|
if r != 'D' {
|
|
|
- return
|
|
|
+ return r
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+CALENDAR_UPDATE:
|
|
|
+ // pc.UpdateCalendarDays()
|
|
|
+ month_t := pc.Calendar_day_t[0]
|
|
|
+ last_played := pc.DB.WhenPlayed()
|
|
|
+
|
|
|
+ for played, hands := range last_played {
|
|
|
+ if played >= month_t {
|
|
|
+ // Ok, it is within the range
|
|
|
+ var played_day int = time.Unix(played, 0).Day()
|
|
|
+ if hands < pc.Total_hands {
|
|
|
+ pc.Calendar_day_status[played_day-1] = 1
|
|
|
+ } else {
|
|
|
+ pc.Calendar_day_status[played_day-1] = 2
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- /*
|
|
|
- CALENDAR_UPDATE:
|
|
|
- pc.UpdateCalendarDays()
|
|
|
- pc.Calendar.Update()
|
|
|
+ log.Printf("%#v\n", pc.Calendar)
|
|
|
+ log.Println("Calendar.Update()")
|
|
|
+ pc.Calendar.Update()
|
|
|
|
|
|
- pc.Door.Write(pc.Calendar.Output())
|
|
|
- */
|
|
|
-}
|
|
|
+ log.Println("Calendar.Output()")
|
|
|
+ pc.Door.Write(pc.Calendar.Output())
|
|
|
|
|
|
-func int32toByteArray(i int32) (arr [4]byte) {
|
|
|
- binary.BigEndian.PutUint32(arr[0:4], uint32(i))
|
|
|
- return
|
|
|
-}
|
|
|
+ var has_playable_day bool = false
|
|
|
+ for x := 0; x < 31; x++ {
|
|
|
+ status := pc.Calendar_day_status[x]
|
|
|
+ if status == 0 || status == 1 {
|
|
|
+ has_playable_day = true
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
-func int64toByteArray(i int64) (arr [8]byte) {
|
|
|
- binary.BigEndian.PutUint64(arr[0:8], uint64(i))
|
|
|
- return
|
|
|
+ if !has_playable_day {
|
|
|
+ pc.Door.Write(door.CRNL + "Sorry, there are no days available to play." + door.CRNL)
|
|
|
+ r = press_a_key(pc.Door)
|
|
|
+ if r < 0 {
|
|
|
+ return r
|
|
|
+ } else {
|
|
|
+ return 'Q'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ log.Println("Choose Day")
|
|
|
+ pc.Door.Write(door.CRNL + "Please choose a day : " + door.SavePos)
|
|
|
+
|
|
|
+AGAIN:
|
|
|
+ log.Println("Input")
|
|
|
+ var toplay string = pc.Door.Input(3)
|
|
|
+ log.Printf("Input was: %s\n", toplay)
|
|
|
+
|
|
|
+ pc.Door.Write(door.RestorePos)
|
|
|
+
|
|
|
+ var number int
|
|
|
+ var err error
|
|
|
+ number, err = strconv.Atoi(toplay)
|
|
|
+ if err != nil {
|
|
|
+ number = 0
|
|
|
+ }
|
|
|
+ if number == 0 {
|
|
|
+ return ' '
|
|
|
+ }
|
|
|
+
|
|
|
+ var status int
|
|
|
+ if number <= 31 {
|
|
|
+ status = pc.Calendar_day_status[number-1]
|
|
|
+ if status == 0 {
|
|
|
+ // play full day
|
|
|
+ pc.Hand = 1
|
|
|
+ pc.Play_day_t = pc.Calendar_day_t[number-1]
|
|
|
+ pc.Play_day = time.Unix(pc.Play_day_t, 0)
|
|
|
+ r = pc.PlayCards()
|
|
|
+ if r == 'D' {
|
|
|
+ goto CALENDAR_UPDATE
|
|
|
+ }
|
|
|
+ return r
|
|
|
+ }
|
|
|
+ if status == 1 {
|
|
|
+ // Play half day
|
|
|
+ pc.Play_day_t = pc.Calendar_day_t[number-1]
|
|
|
+ pc.Play_day = time.Unix(pc.Play_day_t, 0)
|
|
|
+ played := pc.DB.HandsPlayedOnDay(pc.Play_day_t)
|
|
|
+ if played < pc.Total_hands {
|
|
|
+ pc.Hand = played + 1
|
|
|
+ r = pc.PlayCards()
|
|
|
+ if r == 'D' {
|
|
|
+ goto CALENDAR_UPDATE
|
|
|
+ }
|
|
|
+ return r
|
|
|
+ }
|
|
|
+ }
|
|
|
+ goto AGAIN
|
|
|
+ }
|
|
|
+
|
|
|
+ return ' '
|
|
|
}
|
|
|
|
|
|
func (pc *PlayCards) PlayCards() int {
|
|
@@ -491,8 +671,8 @@ func (pc *PlayCards) PlayCards() int {
|
|
|
|
|
|
var game_width int
|
|
|
var game_height int = 20
|
|
|
- pos := CardPos[27]
|
|
|
- game_width = pos.X + 5
|
|
|
+ // pos := &CardPos[27]
|
|
|
+ game_width = CardPos[27].X + 5
|
|
|
MX := door.Width
|
|
|
MY := door.Height
|
|
|
|
|
@@ -523,11 +703,11 @@ Next_Hand:
|
|
|
seed_seq := make([]byte, 0)
|
|
|
|
|
|
for _, seed := range pc.Seeds {
|
|
|
- ba := int32toByteArray(seed)
|
|
|
+ ba := Int32toByteArray(seed)
|
|
|
seed_seq = append(seed_seq, ba[:]...)
|
|
|
// sha1.Sum(ba[:])
|
|
|
}
|
|
|
- pd := int64toByteArray(pc.Play_day_t)
|
|
|
+ pd := Int64toByteArray(pc.Play_day_t)
|
|
|
seed_seq = append(seed_seq, pd[:]...)
|
|
|
// We also need the hand # that we're playing.
|
|
|
seed_seq = append(seed_seq, byte(pc.Hand))
|
|
@@ -828,7 +1008,7 @@ Next_Hand:
|
|
|
// this seemed odd. We quit the game ?
|
|
|
r = 'Q'
|
|
|
}
|
|
|
-
|
|
|
+ break
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -894,7 +1074,7 @@ func (pc *PlayCards) Redraw(Dealing bool) {
|
|
|
|
|
|
{
|
|
|
// Step 1: Draw the deck "source"
|
|
|
- pos := CardPos[29]
|
|
|
+ pos := &CardPos[29]
|
|
|
|
|
|
if pc.Play_card == 51 {
|
|
|
// out of cards
|
|
@@ -930,11 +1110,13 @@ func (pc *PlayCards) Redraw(Dealing bool) {
|
|
|
}
|
|
|
|
|
|
for x := 0; x < x_max; x++ {
|
|
|
- pos := CardPos[x]
|
|
|
+ pos := &CardPos[x]
|
|
|
if Dealing {
|
|
|
time.Sleep(time.Duration(75) * time.Millisecond)
|
|
|
}
|
|
|
|
|
|
+ // log.Printf("Redraw(%d, %d)", x, pos.Level)
|
|
|
+
|
|
|
if Dealing {
|
|
|
c = &pc.DeckPanel.Backs[pos.Level]
|
|
|
c.X = pos.X + pc.Off_X
|