WIP deck methods, added flake, and setup build deps
This commit is contained in:
		
						commit
						777e07035b
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					.direnv/**
 | 
				
			||||||
 | 
					.zig-cache/**
 | 
				
			||||||
 | 
					zig-out/**
 | 
				
			||||||
							
								
								
									
										73
									
								
								build.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								build.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					const std = @import("std");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn build(b: *std.Build) void {
 | 
				
			||||||
 | 
					    const target = b.standardTargetOptions(.{
 | 
				
			||||||
 | 
					        .whitelist = &[_]std.Target.Query{
 | 
				
			||||||
 | 
					            std.Target.Query{ .cpu_arch = .aarch64, .os_tag = .macos },
 | 
				
			||||||
 | 
					            std.Target.Query{ .cpu_arch = .x86_64, .os_tag = .linux },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO
 | 
				
			||||||
 | 
					    // Prefer small size binaries for optimization
 | 
				
			||||||
 | 
					    const optimize = b.standardOptimizeOption(.{ .preferred_optimize_mode = .Debug });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const exe = b.addExecutable(.{
 | 
				
			||||||
 | 
					        .name = "genius_deck",
 | 
				
			||||||
 | 
					        .root_source_file = b.path("src/main.zig"),
 | 
				
			||||||
 | 
					        .target = target,
 | 
				
			||||||
 | 
					        .optimize = optimize,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    // Add zap dependency
 | 
				
			||||||
 | 
					    const zap = b.dependency("zap", .{
 | 
				
			||||||
 | 
					        .target = target,
 | 
				
			||||||
 | 
					        .optimize = optimize,
 | 
				
			||||||
 | 
					        .openssl = false,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    exe.root_module.addImport("zap", zap.module("zap"));
 | 
				
			||||||
 | 
					    b.installArtifact(exe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create Check step for zls
 | 
				
			||||||
 | 
					    const exe_check = b.addExecutable(.{
 | 
				
			||||||
 | 
					        .name = "zerver",
 | 
				
			||||||
 | 
					        .root_source_file = b.path("src/main.zig"),
 | 
				
			||||||
 | 
					        .target = target,
 | 
				
			||||||
 | 
					        .optimize = optimize,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    exe_check.root_module.addImport("zap", zap.module("zap"));
 | 
				
			||||||
 | 
					    const check = b.step("check", "Check if project compiles, used by Zig Language Server");
 | 
				
			||||||
 | 
					    check.dependOn(&exe_check.step);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create Run Step
 | 
				
			||||||
 | 
					    const run_cmd = b.addRunArtifact(exe);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    run_cmd.step.dependOn(b.getInstallStep());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (b.args) |args| {
 | 
				
			||||||
 | 
					        run_cmd.addArgs(args);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const run_step = b.step("run", "Run the app");
 | 
				
			||||||
 | 
					    run_step.dependOn(&run_cmd.step);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Create Test Step
 | 
				
			||||||
 | 
					    const lib_unit_tests = b.addTest(.{
 | 
				
			||||||
 | 
					        .root_source_file = b.path("src/root.zig"),
 | 
				
			||||||
 | 
					        .target = target,
 | 
				
			||||||
 | 
					        .optimize = optimize,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const exe_unit_tests = b.addTest(.{
 | 
				
			||||||
 | 
					        .root_source_file = b.path("src/main.zig"),
 | 
				
			||||||
 | 
					        .target = target,
 | 
				
			||||||
 | 
					        .optimize = optimize,
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const test_step = b.step("test", "Run unit tests");
 | 
				
			||||||
 | 
					    test_step.dependOn(&run_lib_unit_tests.step);
 | 
				
			||||||
 | 
					    test_step.dependOn(&run_exe_unit_tests.step);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								build.zig.zon
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								build.zig.zon
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					.{
 | 
				
			||||||
 | 
					    .name = "genius_deck",
 | 
				
			||||||
 | 
					    .version = "1.0.0",
 | 
				
			||||||
 | 
					    .minimum_zig_version = "0.13.0",
 | 
				
			||||||
 | 
					    .dependencies = .{
 | 
				
			||||||
 | 
					        .zap = .{
 | 
				
			||||||
 | 
					            .url = "https://github.com/zigzap/zap/archive/refs/tags/v0.8.0.tar.gz",
 | 
				
			||||||
 | 
					            .hash = "12209936c3333b53b53edcf453b1670babb9ae8c2197b1ca627c01e72670e20c1a21",
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    .paths = .{
 | 
				
			||||||
 | 
					        "build.zig",
 | 
				
			||||||
 | 
					        "build.zig.zon",
 | 
				
			||||||
 | 
					        "src",
 | 
				
			||||||
 | 
					        "README.md",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										92
									
								
								flake.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								flake.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,92 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "nodes": {
 | 
				
			||||||
 | 
					    "flake-utils": {
 | 
				
			||||||
 | 
					      "inputs": {
 | 
				
			||||||
 | 
					        "systems": "systems"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1710146030,
 | 
				
			||||||
 | 
					        "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
 | 
				
			||||||
 | 
					        "owner": "numtide",
 | 
				
			||||||
 | 
					        "repo": "flake-utils",
 | 
				
			||||||
 | 
					        "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "numtide",
 | 
				
			||||||
 | 
					        "repo": "flake-utils",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nixpkgs": {
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1719690277,
 | 
				
			||||||
 | 
					        "narHash": "sha256-0xSej1g7eP2kaUF+JQp8jdyNmpmCJKRpO12mKl/36Kc=",
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "rev": "2741b4b489b55df32afac57bc4bfd220e8bf617e",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "ref": "nixos-unstable",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "nixpkgs_2": {
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1719942202,
 | 
				
			||||||
 | 
					        "narHash": "sha256-7sP4PzxRsUfRwN8rmFtRvU/nYqTI5YYeIG9P3KJV41g=",
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "rev": "4b015946c99a5bbe9c7a685e66f165aa44644b7d",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "root": {
 | 
				
			||||||
 | 
					      "inputs": {
 | 
				
			||||||
 | 
					        "flake-utils": "flake-utils",
 | 
				
			||||||
 | 
					        "nixpkgs": "nixpkgs",
 | 
				
			||||||
 | 
					        "zlsPkg": "zlsPkg"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "systems": {
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1681028828,
 | 
				
			||||||
 | 
					        "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
 | 
				
			||||||
 | 
					        "owner": "nix-systems",
 | 
				
			||||||
 | 
					        "repo": "default",
 | 
				
			||||||
 | 
					        "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "nix-systems",
 | 
				
			||||||
 | 
					        "repo": "default",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "zlsPkg": {
 | 
				
			||||||
 | 
					      "inputs": {
 | 
				
			||||||
 | 
					        "nixpkgs": "nixpkgs_2"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1,
 | 
				
			||||||
 | 
					        "narHash": "sha256-5LNEr6ek90U0PwmUjyZta4lCB93maBUr86ikbiwSsoU=",
 | 
				
			||||||
 | 
					        "path": "./nix/zls",
 | 
				
			||||||
 | 
					        "type": "path"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "path": "./nix/zls",
 | 
				
			||||||
 | 
					        "type": "path"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "root": "root",
 | 
				
			||||||
 | 
					  "version": 7
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								flake.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								flake.nix
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  description = "An example project using flutter";
 | 
				
			||||||
 | 
					  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
 | 
				
			||||||
 | 
					  inputs.flake-utils.url = "github:numtide/flake-utils";
 | 
				
			||||||
 | 
					  inputs.zlsPkg.url = "path:./nix/zls";
 | 
				
			||||||
 | 
					  outputs = {
 | 
				
			||||||
 | 
					    flake-utils,
 | 
				
			||||||
 | 
					    nixpkgs,
 | 
				
			||||||
 | 
					    zlsPkg,
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					  }:
 | 
				
			||||||
 | 
					  flake-utils.lib.eachDefaultSystem (system: let
 | 
				
			||||||
 | 
					    pkgs = import nixpkgs {
 | 
				
			||||||
 | 
					      inherit system;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    zls = zlsPkg.defaultPackage.${system};
 | 
				
			||||||
 | 
					  in {
 | 
				
			||||||
 | 
					    devShell = pkgs.mkShell {
 | 
				
			||||||
 | 
					        buildInputs = with pkgs; [
 | 
				
			||||||
 | 
					          lldb
 | 
				
			||||||
 | 
					          sqlite
 | 
				
			||||||
 | 
					          zig
 | 
				
			||||||
 | 
					          zls
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								nix/zls/flake.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								nix/zls/flake.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "nodes": {
 | 
				
			||||||
 | 
					    "nixpkgs": {
 | 
				
			||||||
 | 
					      "locked": {
 | 
				
			||||||
 | 
					        "lastModified": 1719942202,
 | 
				
			||||||
 | 
					        "narHash": "sha256-7sP4PzxRsUfRwN8rmFtRvU/nYqTI5YYeIG9P3KJV41g=",
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "rev": "4b015946c99a5bbe9c7a685e66f165aa44644b7d",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "original": {
 | 
				
			||||||
 | 
					        "owner": "NixOS",
 | 
				
			||||||
 | 
					        "repo": "nixpkgs",
 | 
				
			||||||
 | 
					        "type": "github"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "root": {
 | 
				
			||||||
 | 
					      "inputs": {
 | 
				
			||||||
 | 
					        "nixpkgs": "nixpkgs"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "root": "root",
 | 
				
			||||||
 | 
					  "version": 7
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										34
									
								
								nix/zls/flake.nix
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								nix/zls/flake.nix
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  description = "Zig language server";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  inputs = {
 | 
				
			||||||
 | 
					    nixpkgs.url = "github:NixOS/nixpkgs";
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  outputs = {self, nixpkgs}: {
 | 
				
			||||||
 | 
					    defaultPackage.x86_64-linux =
 | 
				
			||||||
 | 
					      with import nixpkgs { system = "x86_64-linux"; };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      stdenv.mkDerivation rec {
 | 
				
			||||||
 | 
					        name = "zls-${version}";
 | 
				
			||||||
 | 
					        version = "0.13.0";
 | 
				
			||||||
 | 
					        src = pkgs.fetchurl {
 | 
				
			||||||
 | 
					          url =  "https://github.com/zigtools/zls/releases/download/${version}/zls-x86_64-linux.tar.xz";
 | 
				
			||||||
 | 
					          sha256 = "sha256-7EwbRcr4jivLnrsWxnBgPMWW5PYhuWGE376DeznNhBA=";
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sourceRoot = ".";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        installPhase = ''
 | 
				
			||||||
 | 
					        install -m755 -D zls $out/bin/zls
 | 
				
			||||||
 | 
					        '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        meta = with lib; {
 | 
				
			||||||
 | 
					          homepage = "https://github.com/zigtools/zls/releases";
 | 
				
			||||||
 | 
					          description = "Zig language server";
 | 
				
			||||||
 | 
					          platforms = platforms.linux;
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        # I still lack stuff here!
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										437
									
								
								src/deck.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										437
									
								
								src/deck.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,437 @@
 | 
				
			|||||||
 | 
					const std = @import("std");
 | 
				
			||||||
 | 
					const assert = std.debug.assert;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const DeckError = error{
 | 
				
			||||||
 | 
					    DuplicateDiscard,
 | 
				
			||||||
 | 
					    Overflow,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const Card = struct { suite: Suit, faceValue: Face };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const Suit = enum(u4) { Diamonds = 0, Clubs = 1, Hearts = 2, Spades = 3 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const Face = enum(u4) {
 | 
				
			||||||
 | 
					    Two = 2,
 | 
				
			||||||
 | 
					    Three = 3,
 | 
				
			||||||
 | 
					    Four = 4,
 | 
				
			||||||
 | 
					    Five = 5,
 | 
				
			||||||
 | 
					    Six = 6,
 | 
				
			||||||
 | 
					    Seven = 7,
 | 
				
			||||||
 | 
					    Eight = 8,
 | 
				
			||||||
 | 
					    Nine = 9,
 | 
				
			||||||
 | 
					    Ten = 10,
 | 
				
			||||||
 | 
					    Jack = 11,
 | 
				
			||||||
 | 
					    Queen = 12,
 | 
				
			||||||
 | 
					    King = 13,
 | 
				
			||||||
 | 
					    Ace = 14,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					comptime {
 | 
				
			||||||
 | 
					    if (@typeInfo(Suit).Enum.fields.len != 4) {
 | 
				
			||||||
 | 
					        @compileError("Only four suites allowed");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (@typeInfo(Face).Enum.fields.len != 13) {
 | 
				
			||||||
 | 
					        @compileError("Only 13 face cards permitted");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const NUM_SUITES = @typeInfo(Suit).Enum.fields.len;
 | 
				
			||||||
 | 
					const NUM_CARDS_IN_SUITE = @typeInfo(Face).Enum.fields.len;
 | 
				
			||||||
 | 
					const MAX_CARDS = NUM_SUITES * NUM_CARDS_IN_SUITE;
 | 
				
			||||||
 | 
					const CARD_STRUCT_SIZE = @sizeOf(Card) / 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// A Bounded Array with a fixed size to fit 52 `Card` structs inside it.
 | 
				
			||||||
 | 
					/// Requires no allocations because of the fixed max size known at compile time.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// pub fn printCards(cards: CardSlice, options: bufPrintCardOptions) void {
 | 
				
			||||||
 | 
					//     std.debug.print("Deck with {d} cards\tBuf len: {d}\n", .{ cards.len, cards.buffer.len });
 | 
				
			||||||
 | 
					//     std.debug.print("--- Bottom of Deck ---\n", .{});
 | 
				
			||||||
 | 
					//     var buf: [18]u8 = undefined;
 | 
				
			||||||
 | 
					//     for (0..cards.len) |cardIdx| {
 | 
				
			||||||
 | 
					//         const card = cards.get(cardIdx);
 | 
				
			||||||
 | 
					//         std.debug.print(" - {d}: {s}\n", .{ cardIdx, bufPrintCard(card, &buf, options) });
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//     std.debug.print("--- Top of Deck ---\n", .{});
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn printDeck(deck: Deck, options: bufPrintCardOptions) void {
 | 
				
			||||||
 | 
					    std.debug.print("Deck with {d} cards\n", .{deck.num_cards});
 | 
				
			||||||
 | 
					    std.debug.print("--- Bottom of Deck ---\n", .{});
 | 
				
			||||||
 | 
					    var buf: [18]u8 = undefined;
 | 
				
			||||||
 | 
					    for (0..deck.num_cards) |cardIdx| {
 | 
				
			||||||
 | 
					        std.debug.print(" - {d}: {s}\n", .{ cardIdx, bufPrintCard(deck.cards[cardIdx], &buf, options) });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    std.debug.print("--- Top of Deck ---\n", .{});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const bufPrintCardOptions = struct {
 | 
				
			||||||
 | 
					    use_icon: bool = true,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					/// Returns a string representation of the card in the `buffer`
 | 
				
			||||||
 | 
					pub fn bufPrintCard(card: Card, buffer: []u8, options: bufPrintCardOptions) []const u8 {
 | 
				
			||||||
 | 
					    // std.debug.print("\n\t{any}", .{card});
 | 
				
			||||||
 | 
					    const fv = @tagName(card.faceValue);
 | 
				
			||||||
 | 
					    const icon = if (options.use_icon) suiteToIcon(card.suite) else @tagName(card.suite);
 | 
				
			||||||
 | 
					    return std.fmt.bufPrint(buffer, "{s} of {s}", .{ fv, icon }) catch return "*err printing card";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn suiteToIcon(s: Suit) []const u8 {
 | 
				
			||||||
 | 
					    return switch (s) {
 | 
				
			||||||
 | 
					        .Spades => "",
 | 
				
			||||||
 | 
					        .Hearts => "",
 | 
				
			||||||
 | 
					        .Clubs => "",
 | 
				
			||||||
 | 
					        .Diamonds => "",
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub const Deck = struct {
 | 
				
			||||||
 | 
					    num_cards: u8 = 0,
 | 
				
			||||||
 | 
					    num_discards: u8 = 0,
 | 
				
			||||||
 | 
					    cb1: [MAX_CARDS]Card = [_]Card{Card{ .suite = .Diamonds, .faceValue = .Two }} ** MAX_CARDS,
 | 
				
			||||||
 | 
					    cb2: [MAX_CARDS]Card = [_]Card{Card{ .suite = .Diamonds, .faceValue = .Two }} ** MAX_CARDS,
 | 
				
			||||||
 | 
					    cards: []Card = undefined,
 | 
				
			||||||
 | 
					    discard_pile: []Card = undefined,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn init(self: *Deck) DeckError!void {
 | 
				
			||||||
 | 
					        // var cardBuf = [_]Card{Card{ .suite = .Diamonds, .faceValue = .Two }} ** MAX_CARDS;
 | 
				
			||||||
 | 
					        self.cards = &self.cb1;
 | 
				
			||||||
 | 
					        // var discardBuf = [_]Card{Card{ .suite = .Diamonds, .faceValue = .Two }} ** MAX_CARDS;
 | 
				
			||||||
 | 
					        self.discard_pile = &self.cb2;
 | 
				
			||||||
 | 
					        // Construct the deck
 | 
				
			||||||
 | 
					        for (0..NUM_SUITES) |suiteIdx| {
 | 
				
			||||||
 | 
					            const suite: Suit = @enumFromInt(suiteIdx);
 | 
				
			||||||
 | 
					            for (0..NUM_CARDS_IN_SUITE) |f| {
 | 
				
			||||||
 | 
					                const faceIdx = NUM_CARDS_IN_SUITE - f + 1;
 | 
				
			||||||
 | 
					                const face: Face = @enumFromInt(faceIdx);
 | 
				
			||||||
 | 
					                self.cards[self.num_cards] = Card{ .suite = suite, .faceValue = face };
 | 
				
			||||||
 | 
					                self.num_cards += 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        assert(self.num_cards == MAX_CARDS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn deal(self: *Deck) ?Card {
 | 
				
			||||||
 | 
					        if (self.num_cards == 0) return null;
 | 
				
			||||||
 | 
					        self.num_cards -= 1;
 | 
				
			||||||
 | 
					        return self.cards[self.num_cards];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn peak(self: *Deck) ?Card {
 | 
				
			||||||
 | 
					        if (self.num_cards == 0) return null;
 | 
				
			||||||
 | 
					        return self.cards[self.num_cards - 1];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn discard(self: *Deck, card: Card) DeckError!void {
 | 
				
			||||||
 | 
					        // Check a duplicate isnt introduced
 | 
				
			||||||
 | 
					        for (0..self.num_discards) |discardIdx| {
 | 
				
			||||||
 | 
					            if (std.meta.eql(self.discard_pile[discardIdx], card)) {
 | 
				
			||||||
 | 
					                return DeckError.DuplicateDiscard;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.discard_pile[self.num_discards] = card;
 | 
				
			||||||
 | 
					        self.num_discards += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn rebuild(self: *Deck) DeckError!void {
 | 
				
			||||||
 | 
					        const newTotal = self.num_cards + self.num_discards;
 | 
				
			||||||
 | 
					        assert(newTotal <= MAX_CARDS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (0..self.num_discards) |disIdx| {
 | 
				
			||||||
 | 
					            self.cards[self.num_cards + disIdx];
 | 
				
			||||||
 | 
					            self.num_cards += 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        self.num_discards = 0;
 | 
				
			||||||
 | 
					        assert(self.num_cards == newTotal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try sort(self.cards);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn order_deck(self: *Deck) DeckError!void {
 | 
				
			||||||
 | 
					        try sort(self.cards);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn sort(cards: []Card, numCards: u8) DeckError!void {
 | 
				
			||||||
 | 
					        if (cards.len <= 1) return;
 | 
				
			||||||
 | 
					        var cb = [MAX_CARDS]?Card{null} ** MAX_CARDS;
 | 
				
			||||||
 | 
					        var sortedGapsDeck: []?Card = cb[0..MAX_CARDS];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (cards) |card| {
 | 
				
			||||||
 | 
					            const cardIdx = faceValueIdx(card.faceValue) + suiteValueIdx(card.suite);
 | 
				
			||||||
 | 
					            sortedGapsDeck[cardIdx] = card;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        var cb2: [MAX_CARDS]Card = undefined;
 | 
				
			||||||
 | 
					        var sortedGaplessDeck = cb2[0..numCards];
 | 
				
			||||||
 | 
					        var glIdx: u8 = 0;
 | 
				
			||||||
 | 
					        for (0..sortedGapsDeck.len) |gIdx| {
 | 
				
			||||||
 | 
					            if (sortedGapsDeck[gIdx] != null) {
 | 
				
			||||||
 | 
					                sortedGaplessDeck[glIdx] = sortedGapsDeck[gIdx];
 | 
				
			||||||
 | 
					                glIdx += 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var newCards = []Card.init(0) catch return DeckError.Overflow;
 | 
				
			||||||
 | 
					        for (sortedGaplessDeck) |card| {
 | 
				
			||||||
 | 
					            newCards.append(card) catch return DeckError.Overflow;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn cloneDeck(deck: *[]Card) DeckError![]Card {
 | 
				
			||||||
 | 
					        var newDeck = []Card.init(0) catch return DeckError.Overflow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (deck.buffer) |card| {
 | 
				
			||||||
 | 
					            newDeck.append(card) catch return DeckError.Overflow;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return newDeck;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test "Deck.cloneDeck" {
 | 
				
			||||||
 | 
					        var deck = Deck{};
 | 
				
			||||||
 | 
					        try deck.init();
 | 
				
			||||||
 | 
					        const clonedCards = try Deck.cloneDeck(&deck.cards);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try std.testing.expectEqual(deck.cards.len, clonedCards.len);
 | 
				
			||||||
 | 
					        for (deck.cards, 0..) |card, i| {
 | 
				
			||||||
 | 
					            try std.testing.expectEqual(card, clonedCards[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn faceValueIdx(f: Face) u8 {
 | 
				
			||||||
 | 
					        const negIdx: i16 = @intCast(@intFromEnum(f));
 | 
				
			||||||
 | 
					        return @intCast(@abs(negIdx - 14));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test "Deck.faceValueIdx" {
 | 
				
			||||||
 | 
					        try std.testing.expectEqual(12, faceValueIdx(Face.Two));
 | 
				
			||||||
 | 
					        try std.testing.expectEqual(1, faceValueIdx(Face.King));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn suiteValueIdx(s: Suit) u8 {
 | 
				
			||||||
 | 
					        const cards: u8 = @intCast(NUM_CARDS_IN_SUITE);
 | 
				
			||||||
 | 
					        return @intFromEnum(s) * cards;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // fn mergeSplit(a: *BoundedArrayOfCards, b: *BoundedArrayOfCards, iBegin: u8, iEnd: u8) void {
 | 
				
			||||||
 | 
					    //     if (iEnd - iBegin <= 1) return;
 | 
				
			||||||
 | 
					    //     const iMiddle: u8 = (iBegin + iEnd) / 2;
 | 
				
			||||||
 | 
					    //     mergeSplit(a, b, iBegin, iMiddle);
 | 
				
			||||||
 | 
					    //     mergeSplit(a, b, iMiddle, iEnd);
 | 
				
			||||||
 | 
					    //     merge(b, a, iBegin, iMiddle, iEnd);
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // /// Merges two arrays of cards, deck `a` is merged into deck `b`
 | 
				
			||||||
 | 
					    // fn merge(a: *BoundedArrayOfCards, b: *BoundedArrayOfCards, iBegin: u8, iMiddle: u8, iEnd: u8) void {
 | 
				
			||||||
 | 
					    //     var i = iBegin;
 | 
				
			||||||
 | 
					    //     var j = iMiddle;
 | 
				
			||||||
 | 
					    //     for (iBegin..iEnd) |k| {
 | 
				
			||||||
 | 
					    //         if (i < iMiddle and (j >= iEnd or gt(a.get(j), a.get(i)))) {
 | 
				
			||||||
 | 
					    //             b.set(k, a.get(i));
 | 
				
			||||||
 | 
					    //             i = i + 1;
 | 
				
			||||||
 | 
					    //         } else {
 | 
				
			||||||
 | 
					    //             b.set(k, a.get(j));
 | 
				
			||||||
 | 
					    //             j = j + 1;
 | 
				
			||||||
 | 
					    //         }
 | 
				
			||||||
 | 
					    //     }
 | 
				
			||||||
 | 
					    // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Greater than comparison function for two cards
 | 
				
			||||||
 | 
					    /// A card is considered greater, if it is found closer
 | 
				
			||||||
 | 
					    /// to the top of the deck when set to the default sort order
 | 
				
			||||||
 | 
					    ///
 | 
				
			||||||
 | 
					    /// Default Order from Top to Bottom is:
 | 
				
			||||||
 | 
					    /// Suites: Spades > Hearts > Clubs > Diamonds
 | 
				
			||||||
 | 
					    /// FaceValue: 2 > 10 > Jack > Queen > King > Ace
 | 
				
			||||||
 | 
					    /// 2 of Spades is on top, Ace of Diamonds is the bottom card
 | 
				
			||||||
 | 
					    fn gt(l: Card, r: Card) bool {
 | 
				
			||||||
 | 
					        const lSuite: u4 = @intFromEnum(l.suite);
 | 
				
			||||||
 | 
					        const lFace: u4 = @intFromEnum(l.faceValue);
 | 
				
			||||||
 | 
					        const rSuite: u4 = @intFromEnum(r.suite);
 | 
				
			||||||
 | 
					        const rFace: u4 = @intFromEnum(r.faceValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (lSuite != rSuite) {
 | 
				
			||||||
 | 
					            return lSuite > rSuite;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // reverse comparison for face value, because 3 (3) is > ace (14)
 | 
				
			||||||
 | 
					        return lFace < rFace;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test "Deck.gt" {
 | 
				
			||||||
 | 
					        const twoHearts = Card{ .suite = .Hearts, .faceValue = .Two };
 | 
				
			||||||
 | 
					        const kingSpades = Card{ .suite = .Spades, .faceValue = .King };
 | 
				
			||||||
 | 
					        const aceSpades = Card{ .suite = .Spades, .faceValue = .Ace };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try std.testing.expect(Deck.gt(kingSpades, twoHearts));
 | 
				
			||||||
 | 
					        try std.testing.expect(Deck.gt(kingSpades, aceSpades));
 | 
				
			||||||
 | 
					        try std.testing.expect(!Deck.gt(aceSpades, aceSpades));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test "Deck.init" {
 | 
				
			||||||
 | 
					    var deck = Deck{};
 | 
				
			||||||
 | 
					    try deck.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(MAX_CARDS, deck.num_cards);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(Card{ .suite = .Diamonds, .faceValue = .Ace }, deck.cards[0]);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(Card{ .suite = .Spades, .faceValue = .Two }, deck.cards[51]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test "Deck.deal" {
 | 
				
			||||||
 | 
					    var deck = Deck{};
 | 
				
			||||||
 | 
					    try deck.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(deck.deal(), Card{ .suite = .Spades, .faceValue = .Two });
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(51, deck.num_cards);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(deck.deal(), Card{ .suite = .Spades, .faceValue = .Three });
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(50, deck.num_cards);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (0..50) |_| {
 | 
				
			||||||
 | 
					        _ = deck.deal();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(0, deck.num_cards);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(null, deck.deal());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test "Deck.peak" {
 | 
				
			||||||
 | 
					    var deck = Deck{};
 | 
				
			||||||
 | 
					    try deck.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(Card{ .suite = .Spades, .faceValue = .Two }, deck.peak());
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(MAX_CARDS, deck.num_cards);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Deal out 20 cards
 | 
				
			||||||
 | 
					    for (0..20) |_| {
 | 
				
			||||||
 | 
					        _ = deck.deal();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(deck.peak(), Card{ .suite = .Hearts, .faceValue = .Nine });
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(deck.num_cards, 32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Try to peak empty deck
 | 
				
			||||||
 | 
					    for (0..32) |_| {
 | 
				
			||||||
 | 
					        _ = deck.deal();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(null, deck.peak());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test "Deck.discard" {
 | 
				
			||||||
 | 
					    var deck = Deck{};
 | 
				
			||||||
 | 
					    try deck.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const twoSpadesCard = deck.deal();
 | 
				
			||||||
 | 
					    try std.testing.expect(twoSpadesCard != null);
 | 
				
			||||||
 | 
					    try std.testing.expect(twoSpadesCard.?.suite == .Spades);
 | 
				
			||||||
 | 
					    try std.testing.expect(twoSpadesCard.?.faceValue == .Two);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Deal out 13 cards
 | 
				
			||||||
 | 
					    for (0..12) |_| {
 | 
				
			||||||
 | 
					        _ = deck.deal();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const twoHeartsCard = deck.deal();
 | 
				
			||||||
 | 
					    try std.testing.expect(twoHeartsCard != null);
 | 
				
			||||||
 | 
					    try std.testing.expect(twoHeartsCard.?.suite == .Hearts);
 | 
				
			||||||
 | 
					    try std.testing.expect(twoHeartsCard.?.faceValue == .Two);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Discard two cards
 | 
				
			||||||
 | 
					    try deck.discard(twoSpadesCard.?);
 | 
				
			||||||
 | 
					    try deck.discard(twoHeartsCard.?);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(2, deck.num_discards);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(twoSpadesCard.?, deck.discard_pile[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Fails to add duplicate card
 | 
				
			||||||
 | 
					    try std.testing.expectError(DeckError.DuplicateDiscard, deck.discard(twoSpadesCard.?));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test "Deck.rebuild" {
 | 
				
			||||||
 | 
					    var deck = Deck{};
 | 
				
			||||||
 | 
					    try deck.init();
 | 
				
			||||||
 | 
					    var buf1 = [_]?Card{null} ** 5;
 | 
				
			||||||
 | 
					    var buf2 = [_]?Card{null} ** 5;
 | 
				
			||||||
 | 
					    var buf3 = [_]?Card{null} ** 5;
 | 
				
			||||||
 | 
					    var playerOneHand: []?Card = &(buf1);
 | 
				
			||||||
 | 
					    var playerTwoHand: []?Card = &(buf2);
 | 
				
			||||||
 | 
					    var playerThreeHand: []?Card = &(buf3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Alternate dealing player one and two hands
 | 
				
			||||||
 | 
					    for (0..10) |i| {
 | 
				
			||||||
 | 
					        if (i % 2 == 0) try playerOneHand.append(deck.deal().?) else try playerTwoHand.append(deck.deal().?);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(5, playerOneHand.len);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(5, playerTwoHand.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Discard top 10 cards from deck
 | 
				
			||||||
 | 
					    for (0..10) |_| {
 | 
				
			||||||
 | 
					        try deck.discard(deck.deal().?);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (0..5) |i| {
 | 
				
			||||||
 | 
					        playerThreeHand[i] = deck.deal().?;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(5, playerThreeHand.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(10, deck.discard_pile.len);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(27, deck.cards.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (0..15) |i| {
 | 
				
			||||||
 | 
					        switch (i % 3) {
 | 
				
			||||||
 | 
					            0 => try deck.discard(playerThreeHand.pop()),
 | 
				
			||||||
 | 
					            1 => try deck.discard(playerOneHand.pop()),
 | 
				
			||||||
 | 
					            2 => try deck.discard(playerTwoHand.pop()),
 | 
				
			||||||
 | 
					            else => unreachable,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(25, deck.discard_pile.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try deck.rebuild();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(0, deck.discard_pile.len);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(52, deck.cards.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(Card{ .suite = .Diamonds, .faceValue = .Ace }, deck.cards[0]);
 | 
				
			||||||
 | 
					    try std.testing.expectEqual(Card{ .suite = .Spades, .faceValue = .Two }, deck.cards[51]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// test "Deck.rebuild with missing cards" {
 | 
				
			||||||
 | 
					//     var deck = Deck{};
 | 
				
			||||||
 | 
					//     try deck.init();
 | 
				
			||||||
 | 
					//     // var playerOneHand = []Card.init(0) catch unreachable;
 | 
				
			||||||
 | 
					//     // var playerTwoHand = []Card.init(0) catch unreachable;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//     // Alternate dealing player one discarding cards
 | 
				
			||||||
 | 
					//     for (0..52) |i| {
 | 
				
			||||||
 | 
					//         switch (i % 4) {
 | 
				
			||||||
 | 
					//             0 => try playerTwoHand.append(deck.deal().?),
 | 
				
			||||||
 | 
					//             1 => try deck.discard(deck.deal().?),
 | 
				
			||||||
 | 
					//             2 => try playerOneHand.append(deck.deal().?),
 | 
				
			||||||
 | 
					//             3 => {
 | 
				
			||||||
 | 
					//                 _ = deck.deal();
 | 
				
			||||||
 | 
					//             },
 | 
				
			||||||
 | 
					//             else => unreachable,
 | 
				
			||||||
 | 
					//         }
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(13, playerOneHand.len);
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(13, playerTwoHand.len);
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(13, deck.discard_pile.len);
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(0, deck.cards.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//     for (0..26) |i| {
 | 
				
			||||||
 | 
					//         switch (i % 2) {
 | 
				
			||||||
 | 
					//             0 => try deck.discard(playerOneHand.pop()),
 | 
				
			||||||
 | 
					//             1 => try deck.discard(playerTwoHand.pop()),
 | 
				
			||||||
 | 
					//             else => unreachable,
 | 
				
			||||||
 | 
					//         }
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(39, deck.discard_pile.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//     try deck.rebuild();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(0, deck.discard_pile.len);
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(39, deck.cards.len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(Card{ .suite = .Diamonds, .faceValue = .Ace }, deck.cards[0]);
 | 
				
			||||||
 | 
					//     try std.testing.expectEqual(Card{ .suite = .Spades, .faceValue = .Two }, deck.cards[38]);
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
							
								
								
									
										6
									
								
								src/main.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/main.zig
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					const std = @import("std");
 | 
				
			||||||
 | 
					const deck = @import("deck.zig");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn main() !void {
 | 
				
			||||||
 | 
					    std.debug.print("It works!\n", .{});
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user