From b1ad14771611b39a07be6607ee78f6b81a20e984 Mon Sep 17 00:00:00 2001 From: Kevin Whitaker Date: Thu, 10 Feb 2022 18:12:53 -0500 Subject: [PATCH 1/7] added red7 card game app --- apps/red7game/ChangeLog | 1 + apps/red7game/README.md | 10 + apps/red7game/app-icon.js | 1 + apps/red7game/icon.png | Bin 0 -> 646 bytes apps/red7game/metadata.json | 15 + apps/red7game/red7.js | 781 +++++++++++++++++++++++++++++++++++ apps/red7game/screenshot.png | Bin 0 -> 2834 bytes 7 files changed, 808 insertions(+) create mode 100644 apps/red7game/ChangeLog create mode 100644 apps/red7game/README.md create mode 100644 apps/red7game/app-icon.js create mode 100644 apps/red7game/icon.png create mode 100644 apps/red7game/metadata.json create mode 100644 apps/red7game/red7.js create mode 100644 apps/red7game/screenshot.png diff --git a/apps/red7game/ChangeLog b/apps/red7game/ChangeLog new file mode 100644 index 000000000..b193cddde --- /dev/null +++ b/apps/red7game/ChangeLog @@ -0,0 +1 @@ +1.0: Initial version of game diff --git a/apps/red7game/README.md b/apps/red7game/README.md new file mode 100644 index 000000000..c6f55be7f --- /dev/null +++ b/apps/red7game/README.md @@ -0,0 +1,10 @@ +# Red 7 Card Game + +Play the card game Red 7 on your Bangle.js. + +![Screenshot](screenshot.png) + +For rules, see [here](https://asmadigames.com/Red7Rules.pdf). + +## Creator +[Kevin Whitaker](https://www.eyecreate.org) diff --git a/apps/red7game/app-icon.js b/apps/red7game/app-icon.js new file mode 100644 index 000000000..3380419c8 --- /dev/null +++ b/apps/red7game/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A6gAAZFykrqwAXlYwTF4PXAC4v/F/4v/F/4v75O7ABfJF8O0ABfCF8PCABG7F4JfhABXCF4LvsRw4vmZIXQF9YuB3YJGF8heJF8u7LxAvkLwXJF9ZeKF8fQLxQvjLwO0BhIvhLwXCF9fCF4PQF9ReNF8JeNF8IuB3b8LF7/JF4PJF9ZeOF75ePF7/QAAIuMd8IAOF/4v/F/4vWwIAXF6gwBADIuTAH4A/AH4Al")) diff --git a/apps/red7game/icon.png b/apps/red7game/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f069bdb82181fb0a853c1175dbeb7e72234ba931 GIT binary patch literal 646 zcmV;10(t$3P)pF8FWQhbW?9;ba!ELWdL_~cP?peYja~^aAhuUa%Y?FJQ@H10uxC@ zK~!jg?U}nvBT*EGzr+=$5i9~0A_Nh{t;9+&g|MZMVkK3I6s8ivNSgf5#ihIwwU&x(D0vQ<@LrpHm*l(6) z{mkd{apruAAP7R=_kRGt{x$YXjJn?og~HcLrIP>r(xPG8cIdip8N&h;i^YDk*;E&B z94ByHH_}-3#b}cW44O<}&A>}M{CP7oiCdcy zn4N`kIojCAN4UL}JT;ZLwHbl+bvdF?uZw_X!RBV-*6D8IUJp)BC0DC3F_E}rx&lW> z@bm<^T;k39N_qmm568!nS5{zd&Pdtx1lnzQc#zy^7%Q8OK)(+M2a*>SV0qbC>2w4x zF5v!NvcXRu(h_L3Ic_VvI zsRUP7l9!f@m;Z=)f%$pkCI80I|1OjX44R=Ah_#75&&%7kt+kdny4|kI|8P|x0K$}x gEe(l`jEw(`-=nIK#X-ik%>V!Z07*qoM6N<$g54G+kN^Mx literal 0 HcmV?d00001 diff --git a/apps/red7game/metadata.json b/apps/red7game/metadata.json new file mode 100644 index 000000000..049717f92 --- /dev/null +++ b/apps/red7game/metadata.json @@ -0,0 +1,15 @@ +{ "id": "red7game", + "name": "Red 7 Card Game", + "shortName" : "Red 7", + "icon": "red7.png", + "version":"1.0", + "description": "An implementation of the card game Red 7 for your watch. Play against the AI and be the last player still in the game to win!", + "tags": "game", + "supports":["BANGLEJS2"], + "readme": "README.md", + "screenshots": [{"url":"screenshot.png"}], + "storage": [ + {"name":"red7game.app.js","url":"red7.js"}, + {"name":"red7game.img","url":"app-icon.js","evaluate":true} + ], +}, diff --git a/apps/red7game/red7.js b/apps/red7game/red7.js new file mode 100644 index 000000000..6b2341144 --- /dev/null +++ b/apps/red7game/red7.js @@ -0,0 +1,781 @@ +const colors = ["red", "orange", "yellow", "green", "blue", "indigo", "violet"]; +const colorRank = {"red":6, "orange":5, "yellow":4, "green":3, "blue":2, "indigo":1, "violet":0}; +const colorsHex = ["#b01f26", "#d45727", "#cfb82e", "#309c47", "#36aeac", "#2c3a93", "#784298"]; +const colorsRules = ["high-\nest\n card", "most\none #", "most\none\ncolor", "most\nevens", "most\nunique\ncolors","most\nin a\nrow", "most\n< 4"]; +const numbers = [1,2,3,4,5,6,7]; +const handPos = [0,24,24*2,24*3,24*4,24*5,24*6]; + +function pointRectangleIntersection(p, r) { + return p.x > r.x1 && p.x < r.x2 && p.y > r.y1 && p.y < r.y2; +} + +class Card { + constructor(cardNum, cardColor) { + this.cardNum = cardNum; + this.cardColor = cardColor; + this.selected = false; + //this.rect = {}; + this.clippedRect = {}; + } + get number() { + return this.cardNum; + } + get color() { + return this.cardColor; + } + set isSelected(sel) { + this.selected = sel; + } + get isSelected() { + return this.isSelected; + } + get fullRect() { + return this.rect; + } + get clipRect() { + return this.clippedRect; + } + draw(x,y,outlined) { + this.rect = {x1: x, x2: x+80, y1: y, y2: y+100}; + this.clippedRect = {x1: x, x2: x+24, y1: y, y2: y+100}; + var colorIndex = colors.indexOf(this.cardColor); + var colorArr = colorsHex[colorIndex]; + var colorRule = colorsRules[colorIndex]; + g.setColor(colorArr); + g.setBgColor(colorArr); + g.fillRect(x,y,x+80,y+100); + if(outlined) { + g.setColor(0,0,0); + g.drawRect(x,y,x+80,y+100); + } + g.setColor(255,255,255); + g.setFont("Vector:40"); + g.setFontAlign(0,0,0); + //g.drawString(this.cardNum,x+40,y+70,true); + g.setFont("6x8:3"); + g.drawString(this.cardNum, x+14, y+14, true); + g.setFont("6x8:2"); + g.drawString(colorRule, x+45, y+50, true); + g.flip(); + } + drawBack(x,y,flipped) { + this.rect = {x1: x, x2: x+80, y1: y, y2: y-100}; + this.clippedRect = {x1: x, x2: x+24, y1: y, y2: y-100}; + g.setColor(255,255,255); + g.setBgColor(0,0,0); + if(flipped) { + g.fillRect(x,y,x+80,-100); + g.setColor(0,0,0); + g.drawRect(x,y,x+80,-100); + g.setFontAlign(0,0,2); + g.setColor(255,0,0); + g.setBgColor(255,255,255); + g.setFont("Vector:40"); + //g.drawString(7,x+40,y-40,true); + } else { + g.fillRect(x,y,x+80,y+100); + g.setColor(0,0,0); + g.drawRect(x,y,x+80,y+100); + g.setFontAlign(0,0,0); + g.setColor(255,0,0); + g.setBgColor(255,255,255); + g.setFont("Vector:40"); + //g.drawString(7,x+40,y+40,true); + } + g.flip(); + } + drawRot(x,y) { + this.rect = {x1: x, x2: x+45, y1: y, y2: y+110}; + var colorIndex = colors.indexOf(this.cardColor); + var colorArr = colorsHex[colorIndex]; + var colorRule = colorsRules[colorIndex]; + g.setColor(colorArr); + g.setBgColor(colorArr); + g.fillRect(x,y,x+110,y+45); + g.setColor(255,255,255); + g.setFontAlign(0,0,0); + g.setFont("6x8:2"); + g.drawString(colorRule, x+55, y+23, true); + g.flip(); + } + drawMicro(x,y) { + this.rect = {x1: x, x2: x+20, y1: y, y2: y+20}; + var colorIndex = colors.indexOf(this.cardColor); + var colorArr = colorsHex[colorIndex]; + g.setColor(colorArr); + g.setBgColor(colorArr); + g.fillRect(x,y,x+20,y+20); + g.setFontAlign(0,0,0); + g.setFont("6x8:2"); + g.setColor(255,255,255); + g.drawString(this.cardNum, x+12, y+12, true); + g.flip(); + } + isHigher(card) { + if(this.number > card.number) { + return true; + } else if(this.number === card.number) { + if(colorRank[this.color] > colorRank[card.color]) { + return true; + } else { + return false; + } + } else { + return false; + } + } +} + +class Hand { + constructor(cards) { + if(typeof cards === "undefined") { + this.hand = []; + } else { + this.hand = cards; + } + } + //Can be single card or array of cards + addCard(card) { + this.hand = this.hand.concat(card); + } + //removes card from hand and returns it + removeCard(card) { + var index = this.hand.indexOf(card); + return this.hand.splice(index,1)[0]; + } + get handCards() { + return this.hand; + } + draw(y, outlined) { + var count = 0; + for(let c of this.hand) { + c.draw(handPos[count],y, outlined); + count++; + } + } + drawMicro(x, y) { + var count = 0; + for(let c of this.hand) { + c.drawMicro(x+handPos[count],y); + count++; + } + } + drawBacks(y, flipped) { + var count = 0; + for(let c of this.hand) { + c.drawBack(handPos[count], y, flipped); + count++; + } + } + checkForClick(cord) { + for(let card of this.hand) { + //If last card, you can check the whole rectangle + if(this.hand.indexOf(card) === this.hand.length - 1) { + if(pointRectangleIntersection(cord,card.fullRect)) { + return card; + } + } + else if(pointRectangleIntersection(cord,card.clippedRect)) { + return card; + } + } + } + bestHighestCard() { + if(this.hand.length === 0) { + return undefined; + } + var highestCard = this.hand[0]; + this.hand.forEach(function(card){ + if(card.isHigher(highestCard)) { + highestCard = card; + } + }); + return new Hand(highestCard); + } + allCardsMatchingNumber(number) { + var matchingHand = new Hand(); + this.hand.forEach(function(card){ + if(card.number === number) { + matchingHand.addCard(card); + } + }); + return matchingHand; + } + bestCardsOneNumber() { + if(this.hand.length === 0) { + return undefined; + } + var counts = {'1':0,'2':0,'3':0,'4':0,'5':0,'6':0,'7':0}; + this.hand.forEach(function(card){ + counts[card.number]++; + }); + var highestNumber = '1'; + for(let n of Object.keys(counts)) { + if(counts[n] > counts[highestNumber]) { + highestNumber = n; + } + if(counts[n] === counts[highestNumber] && n != highestNumber) { + if(n > highestNumber) { + highestNumber = n; + } + } + } + return this.allCardsMatchingNumber(highestNumber); + } + allCardsMatchingColor(color) { + var matchingHand = new Hand(); + this.hand.forEach(function(card) { + if(card.color === color) { + matchingHand.addCard(card); + } + }); + return matchingHand; + } + bestCardsOneColor() { + if(this.hand.length === 0) { + return undefined; + } + var counts = {'red':0, 'orange':0, 'yellow':0, 'green':0, 'blue':0, 'indigo':0, 'violet':0}; + this.hand.forEach(function(card){ + counts[card.color]++; + }); + var highestColor = 'red'; + for(let n of Object.keys(counts)) { + if(counts[n] > counts[highestColor]) { + highestColor = n; + } + if(counts[n] === counts[highestColor] && n != highestColor && counts[highestColor] > 0) { + var h1 = this.allCardsMatchingColor(n); + var h2 = this.allCardsMatchingColor(highestColor); + if(h1.bestHighestCard().handCards.isHigher(h2.bestHighestCard().handCards)) { + highestColor = n; + } + } + } + return this.allCardsMatchingColor(highestColor); + } + bestEvenCards() { + if(this.hand.length === 0) { + return undefined; + } + var matchingHand = new Hand(); + this.hand.forEach(function(card){ + if(card.number % 2 === 0) { + matchingHand.addCard(card); + } + }); + return matchingHand; + } + bestCardsDiffColors() { + if(this.hand.length === 0) { + return undefined; + } + var cloneHand = new Hand(); + for(let c of this.handCards) { + cloneHand.addCard(c); + } + var diffHand = new Hand(); + diffHand.addCard(cloneHand.bestHighestCard().handCards); + cloneHand.removeCard(cloneHand.bestHighestCard().handCards); + while(cloneHand.handCards.length > 0) { + var highCard = cloneHand.bestHighestCard().handCards; + var colorExists = false; + diffHand.handCards.forEach(function(card){ + if(card.color === highCard.color) { + colorExists = true; + } + }); + if(!colorExists) { + diffHand.addCard(highCard); + } + cloneHand.removeCard(highCard); + } + return diffHand; + } + bestRun() { + if(this.hand.length === 0) { + return undefined; + } + var runs = {1:0,2:0,3:0,4:0,5:0,6:0,7:0}; + var highestCard = {0:new Card(0,"violet"),1:new Card(0,"violet"),2:new Card(0,"violet"),3:new Card(0,"violet"),4:new Card(0,"violet"),5:new Card(0,"violet"),6:new Card(0,"violet"),7:new Card(0,"violet")}; + var hands = {0:new Hand(),1:new Hand(),2:new Hand(),3:new Hand(),4:new Hand(),5:new Hand(),6:new Hand(),7:new Hand()}; + for(let start = 1; start < 8; start++) { + //check length of run starting from each number + var currentLen = 0; + var highCard = new Card(0,"violet"); + for(let num = start; num < 8; num++) { + var hasNum = false; + var matchingCard = undefined; + this.hand.forEach(function(card){ + if(card.number === num) { + hasNum = true; + if(matchingCard != undefined) { + if(card.isHigher(matchingCard)) { + matchingCard = card; + } + } else { + matchingCard = card; + } + } + }); + if(hasNum) { + currentLen++; + hands[start].addCard(matchingCard); + highCard = matchingCard; + } else { + break; + } + } + runs[start] = currentLen; + highestCard[start] = highCard; + } + //determine best run + var highestRun = 0; + var highestCount = 0; + for(let n = 1; n < 8; n++) { + if(runs[n] > highestCount) { + highestRun = n; + highestCount = runs[n]; + } else if (runs[n] === highestCount) { + if(highestCard[n].isHigher(highestCard[highestRun])) { + highestRun = n; + highestCount = runs[n]; + } + } + } + return hands[highestRun]; + } + bestCardsBelow4() { + if(this.hand.length === 0) { + return undefined; + } + var matchingHand = new Hand(); + this.hand.forEach(function(card){ + if(card.number < 4) { + matchingHand.addCard(card); + } + }); + return matchingHand; + } +} + +function isWinningCombo(ruleCard, palette, otherPalette) { + //The rules of red7 say that you are winning if you match the rule better than anyone else(more cards match rule with highest card in match breaking ties). + switch(ruleCard.color) { + case "red": + if(palette.bestHighestCard().handCards.isHigher(otherPalette.bestHighestCard().handCards)) return true; + break; + case "orange": + var best1 = palette.bestCardsOneNumber(); + var best2 = otherPalette.bestCardsOneNumber(); + if(best1.handCards.length >= best2.handCards.length) { + if(best1.handCards.length === best2.handCards.length) { + if(best1.bestHighestCard().handCards.isHigher(best2.bestHighestCard().handCards)) { + return true; + } + } else { + return true; + } + } + break; + case "yellow": + var best1 = palette.bestCardsOneColor(); + var best2 = otherPalette.bestCardsOneColor(); + if(best1.handCards.length >= best2.handCards.length) { + if(best1.handCards.length === best2.handCards.length) { + if(best1.bestHighestCard().handCards.isHigher(best2.bestHighestCard().handCards)) { + return true; + } + } else { + return true; + } + } + break; + case "green": + var best1 = palette.bestEvenCards(); + var best2 = otherPalette.bestEvenCards(); + if(best1.handCards.length >= best2.handCards.length) { + if(best1.handCards.length === best2.handCards.length) { + if(best1.handCards.length === 0) { + return false; + } + else if(best1.bestHighestCard().handCards.isHigher(best2.bestHighestCard().handCards)) { + return true; + } + } else { + return true; + } + } + break; + case "blue": + var best1 = palette.bestCardsDiffColors(); + var best2 = otherPalette.bestCardsDiffColors(); + if(best1.handCards.length >= best2.handCards.length) { + if(best1.handCards.length === best2.handCards.length) { + if(best1.bestHighestCard().handCards.isHigher(best2.bestHighestCard().handCards)) { + return true; + } + } else { + return true; + } + } + break; + case "indigo": + var best1 = palette.bestRun(); + var best2 = otherPalette.bestRun(); + if(best1.handCards.length >= best2.handCards.length) { + if(best1.handCards.length === best2.handCards.length) { + if(best1.bestHighestCard().handCards.isHigher(best2.bestHighestCard().handCards)) { + return true; + } + } else { + return true; + } + } + break; + case "violet": + var best1 = palette.bestCardsBelow4(); + var best2 = otherPalette.bestCardsBelow4(); + if(best1.handCards.length >= best2.handCards.length) { + if(best1.handCards.length === best2.handCards.length) { + if(best1.handCards.length === 0) { + return false; + } + else if(best1.bestHighestCard().handCards.isHigher(best2.bestHighestCard().handCards)) { + return true; + } + } else { + return true; + } + } + break; + } + return false; +} + +function canPlay(hand, palette, otherPalette) { + var clonePalette = new Hand(); + for(let c of palette) { + clonePalette.addCard(c); + } + //Check if any card to palette can win first. + for(let c of hand.handCards) { + clonePalette.addCard(c); + if(isWinningCombo(ruleCards.handCards[ruleCards.handCards.length-1],clonePalette, otherPalette)) { + return true; + } + clonePalette.removeCard(c); + } + //Next check for wins with rule change. + for(let c of hand.handCards) { + if(isWinningCombo(c, clonePalette, otherPalette)) { + return true; + } else { + //Check if any palette play can win with rule. + for(let h of hand.handCards) { + if(h === c) {} + else { + clonePalette.addCard(c); + if(isWinningCombo(c, clonePalette, otherPalette)) { + return true; + } + clonePalette.removeCard(c); + } + } + } + } + return false; +} + +class AI { + constructor(hand, palette) { + this.hand = hand; + this.palette = palette; + } + takeTurn(ruleStack, otherPalette) { + var clonePalette = new Hand(); + for(let c of this.palette) { + clonePalette.addCard(c); + } + //Check if any card to palette can win first. + for(let c of this.hand.handCards) { + clonePalette.addCard(c); + if(isWinningCombo(ruleStack.handCards[ruleStack.handCards.length-1],clonePalette, otherPalette)) { + //Play card that wins + this.palette.addCard(c); + this.hand.removeCard(c); + return true; + } + clonePalette.removeCard(c); + } + //Next check for wins with rule change. + for(let c of this.hand.handCards) { + if(isWinningCombo(c, clonePalette, otherPalette)) { + //Play rule card that wins + ruleStack.addCard(c); + this.hand.removeCard(c); + return true; + } else { + //Check if any palette play can win with rule. + for(let h of this.hand.handCards) { + if(h === c) {} + else { + clonePalette.addCard(c); + if(isWinningCombo(c, clonePalette, otherPalette)) { + ruleStack.addCard(c); + this.hand.removeCard(c); + this.palette.addCard(h); + this.hand.removeCard(h); + return true; + } + clonePalette.removeCard(c); + } + } + } + } + return false; + } +} + +function shuffleDeck(deckArray) { + E.srand(Date.now()); + deckArray.sort(() => Math.random() - 0.5); +} + +var deck = []; +var screen = 1; +var startedGame = false; +var playerHand = new Hand(); +var playerPalette = new Hand(); +var AIhand = new Hand(); +var AIPalette = new Hand(); +var ruleCards = new Hand(); +var undoStack = []; +var aiPlayer = new AI(AIhand, AIPalette); + +function drawScreen1_2(card) { + Bangle.removeAllListeners("touch"); + Bangle.removeAllListeners("swipe"); + //determine what actions can be taken + var playedRule = false; + var playedPalette = false; + for(let stack of undoStack) { + if(stack.to === ruleCards) { + playedRule = true; + } + if(stack.to === playerPalette) { + playedPalette = true; + } + } + Bangle.on('swipe', function(direction){ + if(direction === -1 && !playedRule) { + undoStack.push({from:playerHand,to:ruleCards,card:card}); + ruleCards.addCard(card); + playerHand.removeCard(card); + drawScreen1(); + } + if(direction === 1 && !playedPalette) { + undoStack.push({from:playerHand,to:playerPalette,card:card}); + playerPalette.addCard(card); + playerHand.removeCard(card); + drawScreen1(); + } + }); + Bangle.on("touch", function(z,cord){ + if(!pointRectangleIntersection(cord, card.fullRect)) { + drawScreen1(); + } + }); + //draw elements + g.setBgColor(0,0,0); + g.clear(); + playerHand.draw(130, true); + AIhand.drawBacks(40, true); + card.draw(47,47,true); + g.setColor(255,255,255); + if(!playedRule) g.fillPoly([20,50,20,70,40,70,40,90,20,90,20,110,0,80]); + if(!playedPalette) g.fillPoly([155,50,155,70,135,70,135,90,155,90,155,110,175,80]); + g.setFont("4x6:1"); + g.setBgColor(255,255,255); + g.setColor(0,0,0); + if(!playedRule) g.drawString("Rule", 20,80, true); + if(!playedPalette) g.drawString("Palette", 155,80, true); +} + +function drawScreen1() { + Bangle.removeAllListeners("touch"); + Bangle.removeAllListeners("swipe"); + Bangle.on('swipe', function(direction){ + if(direction === -1) { + drawScreen2(); + screen = 2; + } else if(direction === 1) { + drawScreen1(); + screen = 1; + } + }); + g.setBgColor(0,0,0); + g.clear(); + playerHand.draw(130, true); + Bangle.on("touch", function(z,cord){ + var card = playerHand.checkForClick(cord); + if (card !== undefined) { + drawScreen1_2(card); + } + }); + AIhand.drawBacks(40, true); + //Draw win indicator + var winning = isWinningCombo(ruleCards.handCards[ruleCards.handCards.length-1], playerPalette, AIPalette); + winning ? g.setColor(0,255,0) : g.setColor(255,0,0); + g.fillEllipse(50,50,130,70); + g.setFont("4x6:2"); + g.setFontAlign(0,0,0); + g.setColor(255,255,255); + winning ? g.setBgColor(0,255,0) : g.setBgColor(255,0,0); + g.drawString(winning ? "Winning" : "Losing", 90,60, true); + //Draw current rule + var rules = ruleCards.handCards; + if(rules.length > 0) { + rules[rules.length-1].drawRot(40,80); + } +} + +function drawScreen2() { + Bangle.removeAllListeners("touch"); + g.setBgColor(0,0,0); + g.clear(); + g.setColor(255,255,255); + g.setFont("6x8:2"); + g.setFontAlign(0,0,0); + g.drawString("AI Palette",85,40,false); + g.drawString("Your Palette", 85, 130, false); + playerPalette.drawMicro(5,150); + AIPalette.drawMicro(5,0); +} + +function drawScreenHelp() { + E.showAlert("Rules can be found on asmadigames.com").then(function(){drawMainMenu();}); +} + +function drawGameOver(win) { + E.showAlert(win ? "AI has given up. You Win!" : "You cannot play. AI wins.").then(function(){ + startedGame = false; + undoStack = []; + drawMainMenu(); + }); +} + +function finishTurn() { + undoStack = []; + //Check if AI has cards + if(AIhand.handCards.length === 0) { + drawGameOver(true); + } else { + var takenTurn = aiPlayer.takeTurn(ruleCards, playerPalette); + //Check if game over conditions met. + if(!takenTurn) { + drawGameOver(true); + } else if(playerHand.handCards.length === 0) { + drawGameOver(false); + } else if(!canPlay(playerHand, playerPalette, AIPalette)) { + console.log("no play"); + //drawGameOver(false); + drawScreen1(); + } else { + E.showMenu(); + drawScreen1(); + } + } +} + +function resetToNewGame() { + g.setBgColor(0,0,0); + g.clear(); + deck = []; + //Fill deck with cards + for(let c of colors) { + for(let n of numbers) { + deck.push(new Card(n,c)); + } + } + shuffleDeck(deck); + playerHand = new Hand(); + playerHand.addCard(deck.pop()); + playerHand.addCard(deck.pop()); + playerHand.addCard(deck.pop()); + playerHand.addCard(deck.pop()); + playerHand.addCard(deck.pop()); + playerHand.addCard(deck.pop()); + playerHand.addCard(deck.pop()); + playerPalette = new Hand(); + playerPalette.addCard(deck.pop()); + + AIhand = new Hand(); + AIhand.addCard(deck.pop()); + AIhand.addCard(deck.pop()); + AIhand.addCard(deck.pop()); + AIhand.addCard(deck.pop()); + AIhand.addCard(deck.pop()); + AIhand.addCard(deck.pop()); + AIhand.addCard(deck.pop()); + AIPalette = new Hand(); + AIPalette.addCard(deck.pop()); + ruleCards = new Hand(); + ruleCards.addCard(new Card(0,"red")); + undoStack = []; + startedGame = true; + aiPlayer = new AI(AIhand, AIPalette); + //determine first player + if(isWinningCombo(new Card(0,"red"), playerPalette, AIPalette)) { + //AI needs to play first + finishTurn(); + } else { + drawScreen1(); + } +} + +function drawMainMenu() { + Bangle.removeAllListeners("touch"); + Bangle.removeAllListeners("swipe"); + var menu = {"": {"title":"Red 7"}}; + if(startedGame === true) { + menu["Continue"] = function(){ + E.showMenu(); + drawScreen1(); + }; + if(undoStack.length > 0) { + menu["Undo Turn"] = function(){ + for(let stack of undoStack) { + stack.from.addCard(stack.card); + stack.to.removeCard(stack.card); + } + undoStack = []; + E.showMenu(); + drawScreen1(); + }; + } + if(isWinningCombo(ruleCards.handCards[ruleCards.handCards.length-1], playerPalette, AIPalette)) { + menu["Finish Turn"] = function(){ + finishTurn(); + }; + } + } + menu["New Game"] = function() { + E.showMenu(); + resetToNewGame(); + }; + menu["Help"] = function() { + drawScreenHelp(); + }; + menu["Exit"] = function() { + E.showMenu(); + setTimeout(load,300); + }; + E.showMenu(menu); +} + +drawMainMenu(); +setWatch(function(){ + drawMainMenu(); +},BTN, {edge: "rising", debounce: 50, repeat: true}); + diff --git a/apps/red7game/screenshot.png b/apps/red7game/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c1ce8d7916b20c2e4e7272f05e62cca686efc009 GIT binary patch literal 2834 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 Date: Thu, 10 Feb 2022 18:17:50 -0500 Subject: [PATCH 2/7] Update metadata.json --- apps/red7game/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red7game/metadata.json b/apps/red7game/metadata.json index 049717f92..99bf83fa7 100644 --- a/apps/red7game/metadata.json +++ b/apps/red7game/metadata.json @@ -12,4 +12,4 @@ {"name":"red7game.app.js","url":"red7.js"}, {"name":"red7game.img","url":"app-icon.js","evaluate":true} ], -}, +} From d75b7549ff06f041179679e2fb6ea2dd8af8c60c Mon Sep 17 00:00:00 2001 From: eyecreate Date: Thu, 10 Feb 2022 18:33:16 -0500 Subject: [PATCH 3/7] remove extra comma --- apps/red7game/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red7game/metadata.json b/apps/red7game/metadata.json index 99bf83fa7..16b5d9e41 100644 --- a/apps/red7game/metadata.json +++ b/apps/red7game/metadata.json @@ -11,5 +11,5 @@ "storage": [ {"name":"red7game.app.js","url":"red7.js"}, {"name":"red7game.img","url":"app-icon.js","evaluate":true} - ], + ] } From 19156c2bd6a231a2331c0286bf01df61cc8c42b3 Mon Sep 17 00:00:00 2001 From: eyecreate Date: Thu, 10 Feb 2022 18:36:38 -0500 Subject: [PATCH 4/7] fixed wrong file name --- apps/red7game/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/red7game/metadata.json b/apps/red7game/metadata.json index 16b5d9e41..688a900e5 100644 --- a/apps/red7game/metadata.json +++ b/apps/red7game/metadata.json @@ -1,7 +1,7 @@ { "id": "red7game", "name": "Red 7 Card Game", "shortName" : "Red 7", - "icon": "red7.png", + "icon": "icon.png", "version":"1.0", "description": "An implementation of the card game Red 7 for your watch. Play against the AI and be the last player still in the game to win!", "tags": "game", From 63416cae8d7a855bb35d828b6db7e8afb9532347 Mon Sep 17 00:00:00 2001 From: eyecreate Date: Thu, 10 Feb 2022 18:45:18 -0500 Subject: [PATCH 5/7] added details on how to use --- apps/red7game/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/red7game/README.md b/apps/red7game/README.md index c6f55be7f..3f81375c7 100644 --- a/apps/red7game/README.md +++ b/apps/red7game/README.md @@ -6,5 +6,11 @@ Play the card game Red 7 on your Bangle.js. For rules, see [here](https://asmadigames.com/Red7Rules.pdf). +## Usage + +Current rule card is shown in center of screen when viewing your hand. +Swipe left to see your palettes and right on the palette screen to go back to your hand. Tap on a card to see it's details and then swipe either left or right to play the card as a rule or a palette card. +Press the watch button to bring up the menu, which you can undo your card plays, end your turn, or start a new game. + ## Creator [Kevin Whitaker](https://www.eyecreate.org) From 1f9c4b91aad7947dc3fb1cfc7cac2c831c2f7530 Mon Sep 17 00:00:00 2001 From: eyecreate Date: Thu, 10 Feb 2022 18:51:45 -0500 Subject: [PATCH 6/7] add new screenshot --- apps/red7game/screenshot2.png | Bin 0 -> 2115 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/red7game/screenshot2.png diff --git a/apps/red7game/screenshot2.png b/apps/red7game/screenshot2.png new file mode 100644 index 0000000000000000000000000000000000000000..e0546fafa9c04b7ac0322121fd31cc1e79ad5aa3 GIT binary patch literal 2115 zcmeHJTU3&X7XCrNAWbE$Fw2ze4N4~~7_^HYaHgK`*YTxKeKY;8 zdG)_MOXw|RVPl8{OA6kF@I8Ne@*;n1J=VH6f^?(oWrpwdO9pH2lFYdNFR7v5F$XS|CgzhF-^{q?hDK;V{FW0~@RRCx zip_E9flHJRZ8GCmuj$H$4z%Hf1+~BJB0q7# zYDJ=BA5nwJ?}%Jh5R^k5mvlzen8x=s89H$@`o73Rr)$e^Jb{sKhr0D&Fk@#_g8|UO z(K<8N+>xYw1XY@x;}5O)b@@Wb*a_){ke7u2gaFw!ZE0)IAxf?FNdW;U7fC*CH3U^u zw#!|rE) zeD9P1Z#N{AMao|%h^be|!6Riig&9ManA7oNr&Lid`pMa!FQO*};R;PWvI`!>*^%A- zd~Ewp&R$DsyWqnR^v*3oZmnl9vf5p14_G{vFR@62>y2u;E7j`UFmusRS}{>Kuq)ta zwz|G5rgI>5>2VxG4G$O0=jDi@rS zW6wTU4a4UFrA}_os9H%=_W9)eal@a$&x7wesYciBYm8$yGVFUhZp^3d&Lx8ytI{rMgF zCP|$2FP-oP$nc)4V>|0$vtP!Opr37{&35_(yauhe3kuTB-2kcGea1bmv?l2)f*56V5Z7 z)p=M`rFGBQ@i(dt=_aE7=84Snb^R` zThw*?Dy$LG6K{?ldGimst{OZD7F>hw)~nL>e;4!hlH`%s3I*cgZJrx^WfY24+F&OA V3eexmw& Date: Thu, 10 Feb 2022 18:52:23 -0500 Subject: [PATCH 7/7] add new screenshot and allow using emulator --- apps/red7game/metadata.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/red7game/metadata.json b/apps/red7game/metadata.json index 688a900e5..7002720d5 100644 --- a/apps/red7game/metadata.json +++ b/apps/red7game/metadata.json @@ -7,9 +7,10 @@ "tags": "game", "supports":["BANGLEJS2"], "readme": "README.md", - "screenshots": [{"url":"screenshot.png"}], + "allow_emulator": true, + "screenshots": [{"url":"screenshot.png"},{"url":"screenshot2.png"}], "storage": [ {"name":"red7game.app.js","url":"red7.js"}, {"name":"red7game.img","url":"app-icon.js","evaluate":true} ] -} +}