Inital commit

This commit is contained in:
Yurun Chen
2024-09-03 10:24:21 +10:00
commit b8ef7647b1
61 changed files with 526 additions and 0 deletions

3
backend.js Normal file
View File

@@ -0,0 +1,3 @@
class BackendConnection {
}

75
card-v2.js Normal file
View File

@@ -0,0 +1,75 @@
class Card {
#suit
#rank
#value
#faceUp
#color
constructor(suit, rank, vis=false) {
/*Create an object of class Card; provide suit, rank, [visible]*/
this.#suit = suit;
this.#rank = rank;
this.#faceUp = vis;
this.#setColor();
switch(this.#rank) {
case 'J':
this.#value = 11;
break;
case 'Q':
this.#value = 12;
break;
case 'K':
this.#value = 13;
break;
case 'A':
this.#value = 1;
break;
default:
this.#value = parseInt(this.#rank);
}
}
#setColor() {
if (this.#suit[0] == "H" || this.#suit[0] == "D") {
this.#color = "red";
}
else {
this.#color = "black";
}
}
flip() {
/*Inverts the card's visibility*/
this.#faceUp = !this.#faceUp;
}
getVisible() {
/*Returns a Boolean; True if the card face is visible*/
return this.#faceUp;
}
getValue() {
/*Returns the card's equivalent integer value; Ace is 14*/
return this.#value;
}
getRank() {
/*Returns the card's rank*/
return this.#rank;
}
getSuit() {
/*Returns the card's suit*/
return this.#suit;
}
getColor() {
/*Returns the card's color*/
return this.#color;
}
getImageRef() {
/*Returns a string containing a local filename for the card*/
return `${this.#rank + this.#suit}.png`;
}
}

33
cardgame.html Normal file
View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<style>
html {
background-color: Azure;
}
/*canvas styling*/
#canvas {
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin:auto;
border: solid rgb(400,400,300) 4px;
}
</style>
<title>Solitaire - Klondike - Yurun Chen</title>
<!-- <link rel="stylesheet" href="style.css"> -->
<script type="module">import { Canvg } from 'https://cdn.skypack.dev/canvg@^4.0.0';</script>
<script type="text/javascript" defer src="card-v2.js"></script>
<script type="text/javascript" defer src="deck-v2.js"></script>
<!-- main game javascript file-->
<script type="text/javascript" defer src="game.js"></script>
<!-- not currently in use-->
<script type="text/javascript" defer src="backend.js"></script>
</head>
<body>
<canvas id="canvas" width="400" height="300"> </canvas>
</body>
</html>

BIN
cards/10C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
cards/10D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
cards/10H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
cards/10S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
cards/2C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
cards/2D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
cards/2H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
cards/2S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
cards/3C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
cards/3D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
cards/3H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
cards/3S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
cards/4C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
cards/4D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
cards/4H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
cards/4S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
cards/5C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
cards/5D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
cards/5H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
cards/5S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
cards/6C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
cards/6D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
cards/6H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
cards/6S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
cards/7C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
cards/7D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
cards/7H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
cards/7S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
cards/8C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
cards/8D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
cards/8H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
cards/8S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
cards/9C.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
cards/9D.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
cards/9H.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
cards/9S.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
cards/AC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
cards/AD.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
cards/AH.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
cards/AS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
cards/JC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

BIN
cards/JD.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
cards/JH.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

BIN
cards/JS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

BIN
cards/KC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

BIN
cards/KD.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

BIN
cards/KH.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

BIN
cards/KS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
cards/QC.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

BIN
cards/QD.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

BIN
cards/QH.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

BIN
cards/QS.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

BIN
cards/cardBackRed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 KiB

BIN
cards/down_arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
cards/red_back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

BIN
cards/up_arrow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

62
deck-v2.js Normal file
View File

@@ -0,0 +1,62 @@
class Deck {
#deck
constructor() {
/*Initialises a new shuffled deck of 52 cards*/
this.#deck = [];
this.createDeck();
this.shuffle();
}
createDeck() {
/*Creates an array of 52 Card objects*/
const suits = ['H', 'S', 'C', 'D'];
const faces = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K'];
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 13; j++) {
this.#deck.push(new Card(suits[i], faces[j]));
}
}
}
shuffle() {
/*Randomly shuffles the deck*/
for (let i = this.getSize() - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
var temp = this.#deck[i];
this.#deck[i] = this.#deck[j];
this.#deck[j] = temp;
}
}
getSize() {
/*Returns the number of elements in the deck*/
return this.#deck.length;
}
isEmpty() {
/*Returns a Boolean; True if the deck is currently empty*/
return this.getSize() < 1;
}
viewTop() {
/*Returns the topmost card without removing it from the deck, or null if the deck is empty*/
if (!this.isEmpty()) {
return this.#deck[this.getSize() - 1]
}
else {
return null;
}
}
drawCard() {
/*Returns the topmost card in the deck, or null if the deck is empty*/
if (!this.isEmpty()) {
return this.#deck.pop();
}
else {
return null;
}
}
}

353
game.js Normal file
View File

@@ -0,0 +1,353 @@
class Stack {
#items
constructor() {
this.#items = [];
}
push(element) {
this.#items.push(element);
//Add element to the stack
}
pop() {
//Check that the stack is not empty
//Remove the last element from the stack and return it
if (this.isEmpty() == false){
return this.#items.pop()
} else {
return false;
}
}
peek() {
//Check that the stack is not empty
//Return the last element from the stack without removing it
return this.#items[this.#items.length - 1];
}
isEmpty() {
//Return true if the stack is empty
if (this.#items.length == 0){
return true;
} else {
return false;
}
}
size() {
//Return the number of elements in the stack
return this.#items.length;
}
get_items() {
return this.#items;
}
set_items(items) {
this.#items = items;
}
to_array(){
return this.#items;
}
}
//column class
class Column extends Stack{
constructor(){
super();
}
}
//stock stack
class Stock extends Stack {
constructor(){
super();
}
//append card back to stock after wastepile exceeds threshold CRUDE
append(card){
var items = super.get_items();
items.unshift(card);
super.set_items(items);
}
}
class WastePile extends Stack {
constructor(){
super();
}
//clearing waste pile by popping the cards one by one
clear () {
for (i=super.size();i--;i>-1){
super.pop();
}
}
//determines if the waste pile has met the threshold of 3
threshold (){
if (super.size() == 3){
return true;
} else {
return false;
}
}
}
//Object for board layout
class Board {
#waste_pile
#stock_pile
#foundations
#tableau
#deck
constructor (){
//init a deck
this.#deck = new Deck();
this.#tableau = new Array();
this.#stock_pile = new Stock();
this.#waste_pile = new WastePile();
//initialise the 7 columns
for (var i=1; i<8; i++){
this.#tableau.push(new Column());
}
//initialise the value in the 7 columns
for (var j = 1; j<8; j++){
for (var k = j; k>0; k--){
this.#tableau[j-1].push(this.#deck.drawCard());
}
}
var length = this.#deck.getSize();
//initialise the stock pile
for (var k=0; k <= length; k++){
this.#stock_pile.push(this.#deck.drawCard());
}
//reveal top card except stock pile, otherwise it'd be cheating
}
}
//base class for element
class Element{
constructor(x,y) {
this.x = x;
this.y = y;
}
}
class Background extends Element {
#dx
#dy
constructor(){
super(0,0);
this.#dx = 1920;
this.#dy = 1080;
}
resize(scale){
this.#dx = 1920 * scale[0];
this.#dy = 1080 * scale[1];
}
render(ctx){
ctx.fillStyle = "#168a22";
ctx.rect(this.x, this.y, this.#dx, this.#dy);
ctx.stroke();
ctx.fill();
}
}
//view class for different views to extend on
class View {
#element_list
constructor(element_list){
this.#element_list = element_list;
}
resize(scale){
for (var i=0; i< this.#element_list.length; i++) {
this.#element_list[i].resize(scale);
}
}
render(ctx){
for (var i=0; i< this.#element_list.length; i++) {
this.#element_list[i].render(ctx);
}
}
add_element(e){
this.#element_list.append(e);
}
}
//view for single card, bad naming I suppose, as it is not a view (really) more of a element
class CardView extends Element {
#revealed
#img
constructor(revealed, x, y, card){
super(x,y);
this.#revealed = revealed;
this.#img = new Image();
if (revealed) {
this.#img.src = "cards/"+this.#cur_card.getRank()+Array.from(this.#cur_card.getSuit())[0]+".png";
} else {
this.#img.src = "cards/cardBackRed.png";
}
}
render(ctx){
ctx.drawImage(this.#img, x, y);
}
}
//0 orientation for landscape 1 orientation for portrait
class StackView extends View{
#orientation
constructor (orientation,element_list){
super(element_list)
this.#orientation = orientation;
}
}
//view for the stock stack
class StockView extends StackView{
#card_list
#stack
constructor (stack){
super(0, [new CardView(false,50,20)], stack.peek());
this.#stack = stack;
}
}
//view for the waste stack
class WasteView extends StackView{
constructor(){
super(0);
}
}
//view for the vertical columns
class ColumnView extends StackView {
constructor(){
super(1);
}
}
//view for the foundations
class FoundationView extends StackView {
constructor(){
super(1);
}
}
class TableauView{
//passed board object to gen view
constructor (board){
}
}
//canva rendering manager
class RenderMgr{
#ctx
#views
#cur_view
//valid canvas context must be passed
constructor(ctx){
this.#ctx = ctx;
//init bg
this.#cur_view = new View([new Background()]);
}
resize(scale){
//resize every single element present on view
this.#cur_view.resize(scale);
}
render(){
this.#cur_view.render(this.#ctx);
requestAnimationFrame(this.render.bind(this))
}
parse_view_json(json_str) {
var view_list = []
console.log(json_str);
for (var e in json_str){
view_list.push(JSON.parse(e));
}
console.log(view_list);
}
}
class KlondikeGame {
#size_modifier
#board
#ctx
#scale_modifier
#mgr
constructor (){
//intialise a new board
this.#board = new Board();
console.log("initialised board");
//grab context for render manager
this.#ctx = document.getElementById("canvas").getContext("2d");
console.log(this.#board);
//initialise render manager
this.#mgr = new RenderMgr(this.#ctx);
requestAnimationFrame(this.#mgr.render.bind(this.#mgr));
}
//update scale modifier, however only currently fixed to 16:9 aspect ratio.
//all values calculated from modifier * 1920, 1080
update_scale(resolution){
this.#scale_modifier = [resolution[0]/1920, resolution[1]/1080];
this.#mgr.resize(this.#scale_modifier);
}
switch_deck_view(){
}
}
var game_instance = new KlondikeGame();
window.onload = window.onresize = function() {
var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth * 0.9;
canvas.height = window.innerHeight * 0.8;
game_instance.update_scale([canvas.width, canvas.height])
}