瀏覽代碼

Fixed remove card. Display correct revealed card.

Steve Thielemann 3 年之前
父節點
當前提交
dde1bf0353
共有 2 個文件被更改,包括 344 次插入100 次删除
  1. 116 2
      deck.go
  2. 228 98
      playcards.go

+ 116 - 2
deck.go

@@ -355,10 +355,124 @@ func MakeCardStates(decks int) []DeckType {
 	return result
 }
 
-func RemoveCard(c int, off_x int, off_y int, left bool, right bool) string {
+func RemoveCard(c int, back_color string, off_x int, off_y int, left bool, right bool) string {
+	var result string
+
 	Pos := &CardPos[c]
 	if Pos.Level > 1 {
 		Pos.Level--
 	}
-	return ""
+
+	cstr := BackSymbol(Pos.Level)
+	result = door.Goto(Pos.X+off_x, Pos.Y+off_y) + back_color
+
+	if left {
+		result += cstr
+	} else {
+		result += " "
+	}
+	result += "   "
+	if right {
+		result += cstr
+	} else {
+		result += " "
+	}
+
+	result += door.Goto(Pos.X+off_x, Pos.Y+off_y+1) + "     "
+	result += door.Goto(Pos.X+off_x, Pos.Y+off_y+2) + "     "
+	return result
+}
+func Abs(x int) int {
+	if x < 0 {
+		return -x
+	}
+	return x
+}
+
+func FindNextActiveCard(left bool, state *[]DeckType, current int) int {
+	Pos := &CardPos[current]
+	var current_x int = Pos.X
+	var pos int = -1
+	var pos_x int
+	var max_pos int = -1
+	var max_x int = -1
+	var min_pos int = -1
+	var min_x int = 100
+
+	if left {
+		pos_x = 0
+	} else {
+		pos_x = 100
+	}
+
+	for x := 0; x < 28; x++ {
+		if (*state)[x] == 1 {
+			// Possible location
+			if x == current {
+				continue
+			}
+			Pos = &CardPos[x]
+			// find max and min while we're iterating here
+			if Pos.X < min_x {
+				min_pos = x
+				min_x = Pos.X
+			}
+			if Pos.X > max_x {
+				max_pos = x
+				max_x = Pos.X
+			}
+
+			if left {
+				if Pos.X < current_x && Pos.X > pos_x {
+					pos_x = Pos.X
+					pos = x
+				}
+			} else {
+				if Pos.X > current_x && Pos.X < pos_x {
+					pos_x = Pos.X
+					pos = x
+				}
+			}
+		}
+	}
+
+	if pos == -1 {
+		// we couldn't find one
+
+		if left {
+			// use max -- roll around to the right
+			pos = max_pos
+		} else {
+			// use min -- roll around to the left
+			pos = min_pos
+		}
+	}
+	return pos
+}
+
+func FindClosestActiveCard(state *[]DeckType, current int) int {
+	Pos := &CardPos[current]
+	var current_x int = Pos.X
+	var pos int = -1
+	var pos_x int = -1
+
+	for x := 0; x < 28; x++ {
+		if (*state)[x] == 1 {
+			// Possible location
+			if x == current {
+				continue
+			}
+			xPos := &CardPos[x]
+			if pos == -1 {
+				pos = x
+				pos_x = xPos.X
+			} else {
+				if Abs(current_x-xPos.X) < Abs(current_x-pos_x) {
+					pos = x
+					pos_x = xPos.X
+				}
+			}
+		}
+	}
+	return pos
 }

+ 228 - 98
playcards.go

@@ -4,12 +4,12 @@ import (
 	"crypto/sha1"
 	"encoding/binary"
 	"fmt"
+	"log"
 	"math/rand"
 	"red-green/door"
 	"strconv"
 	"strings"
 	"time"
-	"unicode"
 )
 
 func StringToANSIColor(colorCode string) string {
@@ -502,7 +502,6 @@ Next_Hand:
 	// Use play day to seed RNG
 	{
 		// Secret Squirrel method of seeding the RNG
-		Sha1 := sha1.New()
 		seed_seq := make([]byte, 0)
 
 		for _, seed := range pc.Seeds {
@@ -515,8 +514,7 @@ Next_Hand:
 		// We also need the hand # that we're playing.
 		seed_seq = append(seed_seq, byte(pc.Hand))
 
-		Sha1.Write(seed_seq)
-		result := Sha1.Sum(nil)
+		result := sha1.Sum(seed_seq)
 		var seed int64 = int64(binary.BigEndian.Uint64(result[0:8]))
 		pc.RNG.Seed(seed)
 		// I'm seeing changes in the seed_seq bytes, but the seed is the same number.
@@ -608,127 +606,259 @@ Next_Hand:
 
 		if r > 0 {
 			// Not a timeout
-			if r < 0x1000 {
-				// not a function key
-				switch unicode.ToUpper(rune(r)) {
-				case '\x0d':
-					// Next Card
-					if pc.Current_streak > pc.Best_streak {
-						pc.Best_streak = pc.Current_streak
-						save_streak = true
-						pc.Door.Write(pc.StreakPanel.Update())
-					}
 
-					if pc.Play_card < 51 {
-						pc.Play_card++
-						pc.Current_streak = 0
-						pc.Door.Write(pc.StreakPanel.Update())
-						pc.Door.Write(pc.LeftPanel.Update())
-
-						// Deal the next card
-
-						if pc.Play_card == 51 {
-							// out of cards
-							cpos := &CardPos[29]
-							c = &pc.DeckPanel.Backs[0]
-							c.X = cpos.X + pc.Off_X
-							c.Y = cpos.Y + pc.Off_Y
-							pc.Door.Write(c.Output())
-						}
+			/*
+				if r < 0x1000 {
+					// not a function key
+					r = int(unicode.ToUpper(rune(r)))
+				}
+			*/
+
+			switch r {
+			case '\x0d':
+				// Next Card
+				if pc.Current_streak > pc.Best_streak {
+					pc.Best_streak = pc.Current_streak
+					save_streak = true
+					pc.Door.Write(pc.StreakPanel.Update())
+				}
 
-						cpos := &CardPos[28]
-						c = &pc.DeckPanel.Cards[pc.Deck[pc.Play_card]]
+				if pc.Play_card < 51 {
+					pc.Play_card++
+					pc.Current_streak = 0
+					pc.Door.Write(pc.StreakPanel.Update())
+					pc.Door.Write(pc.LeftPanel.Update())
+
+					// Deal the next card
+
+					if pc.Play_card == 51 {
+						// out of cards
+						cpos := &CardPos[29]
+						c = &pc.DeckPanel.Backs[0]
 						c.X = cpos.X + pc.Off_X
 						c.Y = cpos.Y + pc.Off_Y
 						pc.Door.Write(c.Output())
 					}
 
-				case 'R':
-					pc.Redraw(false)
+					cpos := &CardPos[28]
+					c = &pc.DeckPanel.Cards[pc.Deck[pc.Play_card]]
+					c.X = cpos.X + pc.Off_X
+					c.Y = cpos.Y + pc.Off_Y
+					pc.Door.Write(c.Output())
+				}
 
-				case 'Q':
-					// Possibly prompt here for [N]ext hand or [Q]uit
-					if pc.Current_streak > pc.Best_streak {
-						pc.Best_streak = pc.Current_streak
-						pc.Door.Write(pc.StreakPanel.Update())
-					}
+			case 'R', 'r':
+				pc.Redraw(false)
+
+			case 'Q', 'q':
+				// Possibly prompt here for [N]ext hand or [Q]uit
+				if pc.Current_streak > pc.Best_streak {
+					pc.Best_streak = pc.Current_streak
+					pc.Door.Write(pc.StreakPanel.Update())
+				}
+
+				pc.NextQuitPanel.Update()
+				pc.Door.Write(pc.NextQuitPanel.Output())
+
+				if pc.State[26] == 2 {
+					pc.Door.Write(door.ColorText("BLACK"))
+				} else {
+					pc.Door.Write(door.Reset)
+				}
+				if pc.Hand < pc.Total_hands {
+					r = pc.Door.GetOneOf("CNQ")
+				} else {
+					r = pc.Door.GetOneOf("CDQ")
+				}
 
-					pc.NextQuitPanel.Update()
-					pc.Door.Write(pc.NextQuitPanel.Output())
+				if r == 'C' {
+					// Continue
+					pc.Redraw(false)
+				} else {
+					if r == 'D' || r == 'Q' {
+						if pc.Score >= 50 {
+							// pc.DB.SaveScore(now, pc.Time_T, .. pc.Score)
+							_ = pc.Score
+						}
 
-					if pc.State[26] == 2 {
-						pc.Door.Write(door.ColorText("BLACK"))
+						in_game = false
 					} else {
-						pc.Door.Write(door.Reset)
+						if r == 'N' {
+							// pc.DB.SaveScore(...)
+							_ = pc.Score
+							pc.Hand++
+							goto Next_Hand
+						}
 					}
-					if pc.Hand < pc.Total_hands {
-						r = pc.Door.GetOneOf("CNQ")
-					} else {
-						r = pc.Door.GetOneOf("CDQ")
+				}
+
+			case ' ', '5':
+				if CanPlay(pc.Deck[pc.Select_card],
+					pc.Deck[pc.Play_card]) {
+					pc.Current_streak++
+
+					pc.Door.Write(pc.StreakPanel.Update())
+					pc.Score += 10
+
+					if pc.Current_streak > 1 {
+						pc.Score += pc.Current_streak * 5
 					}
+					pc.Door.Write(pc.ScorePanel.Update())
 
-					if r == 'C' {
-						// Continue
-						pc.Redraw(false)
-					} else {
-						if r == 'D' || r == 'Q' {
-							if pc.Score >= 50 {
-								// pc.DB.SaveScore(now, pc.Time_T, .. pc.Score)
-								_ = pc.Score
-							}
+					// Play card
+					pc.State[pc.Select_card] = 2
 
-							in_game = false
-						} else {
-							if r == 'N' {
-								// pc.DB.SaveScore(...)
-								_ = pc.Score
-								pc.Hand++
-								goto Next_Hand
+					{
+						// Swap out the select card with the play card
+						temp := pc.Deck[pc.Select_card]
+						pc.Deck[pc.Select_card] = pc.Deck[pc.Play_card]
+						pc.Deck[pc.Play_card] = temp
+
+						// Select card is invalidated here.  Find new card.
+						check := Unblocks(pc.Select_card)
+						var left bool = false
+						var right bool = false
+
+						for _, chk := range check {
+							blk := Blocks[chk]
+							if blk[0] == pc.Select_card {
+								right = true
+							}
+							if blk[1] == pc.Select_card {
+								left = true
 							}
 						}
-					}
 
-				case ' ', '5':
-					if CanPlay(pc.Deck[pc.Select_card],
-						pc.Deck[pc.Play_card]) {
-						pc.Current_streak++
+						cardback_color := pc.DeckPanel.Backs[1].Lines[0].DefaultColor
+						pc.Door.Write(RemoveCard(pc.Select_card, cardback_color, pc.Off_X, pc.Off_Y, left, right))
+
+						// Redraw play card #28 ("old" select_card)
+						cpos := &CardPos[28]
+						c = &pc.DeckPanel.Cards[pc.Deck[pc.Play_card]]
+						c.X = cpos.X + pc.Off_X
+						c.Y = cpos.Y + pc.Off_Y
+						pc.Door.Write(c.Output())
 
-						pc.Door.Write(pc.StreakPanel.Update())
-						pc.Score += 10
+						// Did we unhide a card?
+						var new_card_shown int = -1
+
+						if len(check) > 0 {
+							for _, chk := range check {
+								blk := Blocks[chk]
+
+								if pc.State[blk[0]] == 2 &&
+									pc.State[blk[1]] == 2 {
+									pc.State[chk] = 1
+									cpos := &CardPos[chk]
+									c = &pc.DeckPanel.Cards[pc.Deck[chk]]
+									c.X = cpos.X + pc.Off_X
+									c.Y = cpos.Y + pc.Off_Y
+									pc.Door.Write(c.Output())
+									new_card_shown = chk
+								}
+							}
+						} else {
+							// top card cleared
+							cpos := &CardPos[pc.Select_card]
+							pc.Door.Write(door.Goto(cpos.X+pc.Off_X, cpos.Y+pc.Off_Y) + Bonus())
 
-						if pc.Current_streak > 1 {
-							pc.Score += pc.Current_streak * 5
+							pc.Score += 100
+							pc.State[pc.Select_card] = 3 // Handle in "redraw"
+							pc.Door.Write(pc.ScorePanel.Update())
 						}
-						pc.Door.Write(pc.ScorePanel.Update())
-
-						// Play card
-						pc.State[pc.Select_card] = 2
-
-						{
-							// Swap out the select card with the play card
-							temp := pc.Deck[pc.Select_card]
-							pc.Deck[pc.Select_card] = pc.Deck[pc.Play_card]
-							pc.Deck[pc.Play_card] = temp
-
-							// Select card is invalidated here.  Find new card.
-							check := Unblocks(pc.Select_card)
-							var left bool = false
-							var right bool = false
-
-							for _, c := range check {
-								blk := Blocks[c]
-								if blk[0] == pc.Select_card {
-									right = true
+
+						// Find new number for select_card.
+						if new_card_shown != -1 {
+							pc.Select_card = new_card_shown
+						} else {
+							new_select := FindClosestActiveCard(&pc.State, pc.Select_card)
+
+							if new_select != -1 {
+								pc.Select_card = new_select
+							} else {
+								log.Println("Winner")
+								pc.Select_card = -1
+
+								pc.Score += 15 * (51 - pc.Play_card)
+								pc.Door.Write(pc.ScorePanel.Update())
+
+								// Save Score
+								// pc.DB.SaveScore(now, pc.Play_day_t, pc.Hand, pc.Score)
+								pc.NextQuitPanel.Update()
+								pc.Door.Write(pc.NextQuitPanel.Output())
+
+								if pc.State[26] == 2 {
+									pc.Door.Write(door.ColorText("BLACK"))
+								} else {
+									pc.Door.Write(door.Reset)
 								}
-								if blk[1] == pc.Select_card {
-									left = true
+
+								if pc.Hand < pc.Total_hands {
+									r = pc.Door.GetOneOf("NQ")
+								} else {
+									r = pc.Door.GetOneOf("DQ")
 								}
-							}
 
-							RemoveCard(pc.Select_card, pc.Off_X, pc.Off_Y, left, right)
+								if r == 'N' {
+									pc.Hand++
+									goto Next_Hand
+								}
+
+								in_game = false
+
+								// if r == 'D' ?
+
+								if r == 'Q' {
+									r = 'Q'
+								}
+
+							}
 						}
+
+						// Update the select_card marker
+						Pos := &CardPos[pc.Select_card]
+						c = &pc.DeckPanel.Mark[1]
+						c.X = Pos.X + pc.Off_X + 2
+						c.Y = Pos.Y + pc.Off_Y + 2
+						pc.Door.Write(c.Output() + door.Reset)
 					}
 				}
+
+			case door.XKEY_LEFT_ARROW, '4':
+				var new_select int = FindNextActiveCard(true, &pc.State, pc.Select_card)
+
+				if new_select >= 0 {
+					Pos := &CardPos[pc.Select_card]
+					c = &pc.DeckPanel.Mark[0]
+					c.X = Pos.X + pc.Off_X + 2
+					c.Y = Pos.Y + pc.Off_Y + 2
+					pc.Door.Write(c.Output())
+
+					pc.Select_card = new_select
+					Pos = &CardPos[pc.Select_card]
+					c = &pc.DeckPanel.Mark[1]
+					c.X = Pos.X + pc.Off_X + 2
+					c.Y = Pos.Y + pc.Off_Y + 2
+					pc.Door.Write(c.Output() + door.Reset)
+				}
+
+			case door.XKEY_RIGHT_ARROW, '6':
+				var new_select int = FindNextActiveCard(false, &pc.State, pc.Select_card)
+
+				if new_select >= 0 {
+					Pos := &CardPos[pc.Select_card]
+					c = &pc.DeckPanel.Mark[0]
+					c.X = Pos.X + pc.Off_X + 2
+					c.Y = Pos.Y + pc.Off_Y + 2
+					pc.Door.Write(c.Output())
+
+					pc.Select_card = new_select
+					Pos = &CardPos[pc.Select_card]
+					c = &pc.DeckPanel.Mark[1]
+					c.X = Pos.X + pc.Off_X + 2
+					c.Y = Pos.Y + pc.Off_Y + 2
+					pc.Door.Write(c.Output() + door.Reset)
+				}
 			}
 		}
 	}