mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-22 23:26:40 -08:00
Removed spaces from top-level directory names.
Spaces tend to cause annoyances in a Unix-style shell environment. This change fixes that.
This commit is contained in:
549
10_Blackjack/javascript/blackjack.js
Normal file
549
10_Blackjack/javascript/blackjack.js
Normal file
@@ -0,0 +1,549 @@
|
||||
// BLACKJACK
|
||||
//
|
||||
// Converted from BASIC to Javascript by Oscar Toledo G. (nanochess)
|
||||
//
|
||||
|
||||
function print(str)
|
||||
{
|
||||
document.getElementById("output").appendChild(document.createTextNode(str));
|
||||
}
|
||||
|
||||
function input()
|
||||
{
|
||||
var input_element;
|
||||
var input_str;
|
||||
|
||||
return new Promise(function (resolve) {
|
||||
input_element = document.createElement("INPUT");
|
||||
|
||||
print("? ");
|
||||
input_element.setAttribute("type", "text");
|
||||
input_element.setAttribute("length", "50");
|
||||
document.getElementById("output").appendChild(input_element);
|
||||
input_element.focus();
|
||||
input_str = undefined;
|
||||
input_element.addEventListener("keydown", function (event) {
|
||||
if (event.keyCode == 13) {
|
||||
input_str = input_element.value;
|
||||
document.getElementById("output").removeChild(input_element);
|
||||
print(input_str);
|
||||
print("\n");
|
||||
resolve(input_str);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function tab(space)
|
||||
{
|
||||
var str = "";
|
||||
while (space-- > 0)
|
||||
str += " ";
|
||||
return str;
|
||||
}
|
||||
|
||||
var da = [];
|
||||
|
||||
var pa = [];
|
||||
var qa = [];
|
||||
var ca = [];
|
||||
var ta = [];
|
||||
var sa = [];
|
||||
var ba = [];
|
||||
var za = [];
|
||||
var ra = [];
|
||||
|
||||
var ds = "N A 2 3 4 5 6 7N 8 9 10 J Q K";
|
||||
var is = "H,S,D,/,"
|
||||
|
||||
var q;
|
||||
var aa;
|
||||
var ab;
|
||||
var ac;
|
||||
var h;
|
||||
var h1;
|
||||
|
||||
function af(q) {
|
||||
return q >= 22 ? q - 11 : q;
|
||||
}
|
||||
|
||||
function reshuffle()
|
||||
{
|
||||
print("RESHUFFLING\n");
|
||||
for (; d >= 1; d--)
|
||||
ca[--c] = da[d];
|
||||
for (c1 = 52; c1 >= c; c1--) {
|
||||
c2 = Math.floor(Math.random() * (c1 - c + 1)) + c;
|
||||
c3 = ca[c2];
|
||||
ca[c2] = ca[c1];
|
||||
ca[c1] = c3;
|
||||
}
|
||||
}
|
||||
|
||||
// Subroutine to get a card.
|
||||
function get_card()
|
||||
{
|
||||
if (c >= 51)
|
||||
reshuffle();
|
||||
return ca[c++];
|
||||
}
|
||||
|
||||
// Card printing subroutine
|
||||
function card_print(x)
|
||||
{
|
||||
print(ds.substr(3 * x - 3, 3) + " ");
|
||||
}
|
||||
|
||||
// Alternate card printing subroutine
|
||||
function alt_card_print(x)
|
||||
{
|
||||
print(" " + ds.substr(3 * x - 2, 2) + " ");
|
||||
}
|
||||
|
||||
// Subroutine to add card 'which' to total 'q'
|
||||
function add_card(which)
|
||||
{
|
||||
x1 = which;
|
||||
if (x1 > 10)
|
||||
x1 = 10;
|
||||
q1 = q + x1;
|
||||
if (q < 11) {
|
||||
if (which <= 1) {
|
||||
q += 11;
|
||||
return;
|
||||
}
|
||||
if (q1 >= 11)
|
||||
q = q1 + 11;
|
||||
else
|
||||
q = q1;
|
||||
return;
|
||||
}
|
||||
if (q <= 21 && q1 > 21)
|
||||
q = q1 + 1;
|
||||
else
|
||||
q = q1;
|
||||
if (q >= 33)
|
||||
q = -1;
|
||||
}
|
||||
|
||||
// Subroutine to evaluate hand 'which'. Total is put into
|
||||
// qa[which]. Totals have the following meaning:
|
||||
// 2-10...hard 2-10
|
||||
// 11-21...soft 11-21
|
||||
// 22-32...hard 11-21
|
||||
// 33+....busted
|
||||
function evaluate_hand(which)
|
||||
{
|
||||
q = 0;
|
||||
for (q2 = 1; q2 <= ra[which]; q2++) {
|
||||
add_card(pa[i][q2]);
|
||||
}
|
||||
qa[which] = q;
|
||||
}
|
||||
|
||||
// Subroutine to add a card to row i
|
||||
function add_card_to_row(i, x) {
|
||||
ra[i]++;
|
||||
pa[i][ra[i]] = x;
|
||||
q = qa[i];
|
||||
add_card(x);
|
||||
qa[i] = q;
|
||||
if (q < 0) {
|
||||
print("...BUSTED\n");
|
||||
discard_row(i);
|
||||
}
|
||||
}
|
||||
|
||||
// Subroutine to discard row i
|
||||
function discard_row(i) {
|
||||
while (ra[i]) {
|
||||
d++;
|
||||
da[d] = pa[i][ra[i]];
|
||||
ra[i]--;
|
||||
}
|
||||
}
|
||||
|
||||
// Prints total of hand i
|
||||
function print_total(i) {
|
||||
print("\n");
|
||||
aa = qa[i];
|
||||
total_aa();
|
||||
print("TOTAL IS " + aa + "\n");
|
||||
}
|
||||
|
||||
function total_aa()
|
||||
{
|
||||
if (aa >= 22)
|
||||
aa -= 11;
|
||||
}
|
||||
|
||||
function total_ab()
|
||||
{
|
||||
if (ab >= 22)
|
||||
ab -= 11;
|
||||
}
|
||||
|
||||
function total_ac()
|
||||
{
|
||||
if (ac >= 22)
|
||||
ac -= 11;
|
||||
}
|
||||
|
||||
function process_input(str)
|
||||
{
|
||||
str = str.substr(0, 1);
|
||||
for (h = 1; h <= h1; h += 2) {
|
||||
if (str == is.substr(h - 1, 1))
|
||||
break;
|
||||
}
|
||||
if (h <= h1) {
|
||||
h = (h + 1) / 2;
|
||||
return 0;
|
||||
}
|
||||
print("TYPE " + is.substr(0, h1 - 1) + " OR " + is.substr(h1 - 1, 2) + " PLEASE");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Main program
|
||||
async function main()
|
||||
{
|
||||
print(tab(31) + "BLACK JACK\n");
|
||||
print(tab(15) + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n");
|
||||
print("\n");
|
||||
print("\n");
|
||||
print("\n");
|
||||
// --pa[i][j] IS THE JTH CARD IN HAND I, qa[i] IS TOTAL OF HAND I
|
||||
// --C IS THE DECK BEING DEALT FROM, D IS THE DISCARD PILE,
|
||||
// --ta[i] IS THE TOTAL FOR PLAYER I, sa[i] IS THE TOTAL THIS HAND FOR
|
||||
// --PLAYER I, ba[i] IS TH BET FOR HAND I
|
||||
// --ra[i] IS THE LENGTH OF pa[I,*]
|
||||
|
||||
// --Program starts here
|
||||
// --Initialize
|
||||
for (i = 1; i <= 15; i++)
|
||||
pa[i] = [];
|
||||
for (i = 1; i <= 13; i++)
|
||||
for (j = 4 * i - 3; j <= 4 * i; j++)
|
||||
da[j] = i;
|
||||
d = 52;
|
||||
c = 53;
|
||||
print("DO YOU WANT INSTRUCTIONS");
|
||||
str = await input();
|
||||
if (str.toUpperCase().substr(0, 1) != "N") {
|
||||
print("THIS IS THE GAME OF 21. AS MANY AS 7 PLAYERS MAY PLAY THE\n");
|
||||
print("GAME. ON EACH DEAL, BETS WILL BE ASKED FOR, AND THE\n");
|
||||
print("PLAYERS' BETS SHOULD BE TYPED IN. THE CARDS WILL THEN BE\n");
|
||||
print("DEALT, AND EACH PLAYER IN TURN PLAYS HIS HAND. THE\n");
|
||||
print("FIRST RESPONSE SHOULD BE EITHER 'D', INDICATING THAT THE\n");
|
||||
print("PLAYER IS DOUBLING DOWN, 'S', INDICATING THAT HE IS\n");
|
||||
print("STANDING, 'H', INDICATING HE WANTS ANOTHER CARD, OR '/',\n");
|
||||
print("INDICATING THAT HE WANTS TO SPLIT HIS CARDS. AFTER THE\n");
|
||||
print("INITIAL RESPONSE, ALL FURTHER RESPONSES SHOULD BE 'S' OR\n");
|
||||
print("'H', UNLESS THE CARDS WERE SPLIT, IN WHICH CASE DOUBLING\n");
|
||||
print("DOWN IS AGAIN PERMITTED. IN ORDER TO COLLECT FOR\n");
|
||||
print("BLACKJACK, THE INITIAL RESPONSE SHOULD BE 'S'.\n");
|
||||
}
|
||||
while (1) {
|
||||
print("NUMBER OF PLAYERS");
|
||||
n = parseInt(await input());
|
||||
print("\n");
|
||||
if (n < 1 || n > 7)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
for (i = 1; i <= 8; i++)
|
||||
ta[i] = 0;
|
||||
d1 = n + 1;
|
||||
while (1) {
|
||||
if (2 * d1 + c >= 52) {
|
||||
reshuffle();
|
||||
}
|
||||
if (c == 2)
|
||||
c--;
|
||||
for (i = 1; i <= n; i++)
|
||||
za[i] = 0;
|
||||
for (i = 1; i <= 15; i++)
|
||||
ba[i] = 0;
|
||||
for (i = 1; i <= 15; i++)
|
||||
qa[i] = 0;
|
||||
for (i = 1; i <= 7; i++)
|
||||
sa[i] = 0;
|
||||
for (i = 1; i <= 15; i++)
|
||||
ra[i] = 0;
|
||||
print("BETS:\n");
|
||||
for (i = 1; i <= n; i++) {
|
||||
do {
|
||||
print("#" + i + " ");
|
||||
za[i] = parseFloat(await input());
|
||||
} while (za[i] <= 0 || za[i] > 500) ;
|
||||
}
|
||||
for (i = 1; i <= n; i++)
|
||||
ba[i] = za[i];
|
||||
print("PLAYER");
|
||||
for (i = 1; i <= n; i++) {
|
||||
print(" " + i + " ");
|
||||
}
|
||||
print("DEALER\n");
|
||||
for (j = 1; j <= 2; j++) {
|
||||
print(tab(5));
|
||||
for (i = 1; i <= d1; i++) {
|
||||
pa[i][j] = get_card();
|
||||
if (j == 1 || i <= n)
|
||||
alt_card_print(pa[i][j]);
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
for (i = 1; i <= d1; i++)
|
||||
ra[i] = 2;
|
||||
// --Test for insurance
|
||||
if (pa[d1][1] <= 1) {
|
||||
print("ANY INSURANCE");
|
||||
str = await input();
|
||||
if (str.substr(0, 1) == "Y") {
|
||||
print("INSURANCE BETS\n");
|
||||
for (i = 1; i <= n; i++) {
|
||||
do {
|
||||
print("#" + i + " ");
|
||||
za[i] = parseFloat(await input());
|
||||
} while (za[i] < 0 || za[i] > ba[i] / 2) ;
|
||||
}
|
||||
for (i = 1; i <= n; i++)
|
||||
sa[i] = za[i] * ((pa[d1][2] >= 10 ? 3 : 0) - 1);
|
||||
}
|
||||
}
|
||||
// --Test for dealer blackjack
|
||||
l1 = 1;
|
||||
l2 = 1;
|
||||
if (pa[d1][1] == 1 && pa[d1][2] > 9) {
|
||||
l1 = 0;
|
||||
l2 = 0;
|
||||
}
|
||||
if (pa[d1][2] == 1 && pa[d1][1] > 9) {
|
||||
l1 = 0;
|
||||
l2 = 0;
|
||||
}
|
||||
if (l1 == 0 && l2 == 0) {
|
||||
print("\n");
|
||||
print("DEALER HAS A" + ds.substr(3 * pa[d1][2] - 3, 3) + " IN THE HOLE FOR BLACKJACK\n");
|
||||
for (i = 1; i <= d1; i++)
|
||||
evaluate_hand(i);
|
||||
} else {
|
||||
// --No dealer blackjack
|
||||
if (pa[d1][1] <= 1 || pa[d1][1] >= 10) {
|
||||
print("\n");
|
||||
print("NO DEALER BLACKJACK.\n");
|
||||
}
|
||||
// --Now play the hands
|
||||
for (i = 1; i <= n; i++) {
|
||||
print("PLAYER " + i + " ");
|
||||
h1 = 7;
|
||||
do {
|
||||
str = await input();
|
||||
} while (process_input(str)) ;
|
||||
if (h == 1) { // Player wants to be hit
|
||||
evaluate_hand(i);
|
||||
h1 = 3;
|
||||
x = get_card();
|
||||
print("RECEIVED A");
|
||||
card_print(x);
|
||||
add_card_to_row(i, x);
|
||||
if (q > 0)
|
||||
print_total(i);
|
||||
} else if (h == 2) { // Player wants to stand
|
||||
evaluate_hand(i);
|
||||
if (qa[i] == 21) {
|
||||
print("BLACKJACK\n");
|
||||
sa[i] = sa[i] + 1.5 * ba[i];
|
||||
ba[i] = 0;
|
||||
discard_row(i);
|
||||
} else {
|
||||
print_total(i);
|
||||
}
|
||||
} else if (h == 3) { // Player wants to double down
|
||||
evaluate_hand(i);
|
||||
h1 = 3;
|
||||
h = 1;
|
||||
while (1) {
|
||||
if (h == 1) { // Hit
|
||||
x = get_card();
|
||||
print("RECEIVED A");
|
||||
card_print(x);
|
||||
add_card_to_row(i, x);
|
||||
if (q < 0)
|
||||
break;
|
||||
print("HIT");
|
||||
} else if (h == 2) { // Stand
|
||||
print_total(i);
|
||||
break;
|
||||
}
|
||||
do {
|
||||
str = await input();
|
||||
} while (process_input(str)) ;
|
||||
h1 = 3;
|
||||
}
|
||||
} else if (h == 4) { // Player wants to split
|
||||
l1 = pa[i][1];
|
||||
if (l1 > 10)
|
||||
l1 = 10;
|
||||
l2 = pa[i][2];
|
||||
if (l2 > 10)
|
||||
l2 = 10;
|
||||
if (l1 != l2) {
|
||||
print("SPLITTING NOT ALLOWED.\n");
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
// --Play out split
|
||||
i1 = i + d1;
|
||||
ra[i1] = 2;
|
||||
pa[i1][1] = pa[i1][2];
|
||||
ba[i + d1] = ba[i];
|
||||
x = get_card();
|
||||
print("FIRST HAND RECEIVES A");
|
||||
card_print(x);
|
||||
pa[i][2] = x;
|
||||
evaluate_hand(i);
|
||||
print("\n");
|
||||
x = get_card();
|
||||
print("SECOND HAND RECEIVES A");
|
||||
i = i1;
|
||||
card_print(x);
|
||||
pa[i][2] = x;
|
||||
evaluate_hand(i);
|
||||
print("\n");
|
||||
i = i1 - d1;
|
||||
if (pa[i][1] != 1) {
|
||||
// --Now play the two hands
|
||||
do {
|
||||
|
||||
print("HAND " + (i > d1 ? 2 : 1) + " ");
|
||||
h1 = 5;
|
||||
while (1) {
|
||||
do {
|
||||
str = await input();
|
||||
} while (process_input(str)) ;
|
||||
h1 = 3;
|
||||
if (h == 1) { // Hit
|
||||
x = get_card();
|
||||
print("RECEIVED A");
|
||||
card_print(x);
|
||||
add_card_to_row(i, x);
|
||||
if (q < 0)
|
||||
break;
|
||||
print("HIT");
|
||||
} else if (h == 2) { // Stand
|
||||
print_total(i);
|
||||
break;
|
||||
} else { // Double
|
||||
x = get_card();
|
||||
ba[i] *= 2;
|
||||
print("RECEIVED A");
|
||||
card_print(x);
|
||||
add_card_to_row(i, x);
|
||||
if (q > 0)
|
||||
print_total(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
i += d1;
|
||||
} while (i == i1) ;
|
||||
i = i1 - d1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// --Test for playing dealer's hand
|
||||
evaluate_hand(i);
|
||||
for (i = 1; i <= n; i++) {
|
||||
if (ra[i] > 0 || ra[i + d1] > 0)
|
||||
break;
|
||||
}
|
||||
if (i > n) {
|
||||
print("DEALER HAD A");
|
||||
x = pa[d1][2];
|
||||
card_print(x);
|
||||
print(" CONCEALED.\n");
|
||||
} else {
|
||||
print("DEALER HAS A" + ds.substr(3 * pa[d1][2] - 3, 3) + " CONCEALED ");
|
||||
i = d1;
|
||||
aa = qa[i];
|
||||
total_aa();
|
||||
print("FOR A TOTAL OF " + aa + "\n");
|
||||
if (aa <= 16) {
|
||||
print("DRAWS");
|
||||
do {
|
||||
|
||||
x = get_card();
|
||||
alt_card_print(x);
|
||||
add_card_to_row(i, x);
|
||||
aa = q;
|
||||
total_aa();
|
||||
} while (q > 0 && aa < 17) ;
|
||||
if (q < 0) {
|
||||
qa[i] = q + 0.5;
|
||||
} else {
|
||||
qa[i] = q;
|
||||
}
|
||||
if (q >= 0) {
|
||||
aa = q;
|
||||
total_aa();
|
||||
print("---TOTAL IS " + aa + "\n");
|
||||
}
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
}
|
||||
// --TALLY THE RESULT
|
||||
str = "LOSES PUSHES WINS "
|
||||
print("\n");
|
||||
for (i = 1; i <= n; i++) {
|
||||
aa = qa[i]
|
||||
total_aa();
|
||||
ab = qa[i + d1];
|
||||
total_ab();
|
||||
ac = qa[d1];
|
||||
total_ac();
|
||||
signaaac = aa - ac;
|
||||
if (signaaac) {
|
||||
if (signaaac < 0)
|
||||
signaaac = -1;
|
||||
else
|
||||
signaaac = 1;
|
||||
}
|
||||
signabac = ab - ac;
|
||||
if (signabac) {
|
||||
if (signabac < 0)
|
||||
signabac = -1;
|
||||
else
|
||||
signabac = 1;
|
||||
}
|
||||
sa[i] = sa[i] + ba[i] * signaaac + ba[i + d1] * signabac;
|
||||
ba[i + d1] = 0;
|
||||
print("PLAYER " + i + " ");
|
||||
signsai = sa[i];
|
||||
if (signsai) {
|
||||
if (signsai < 0)
|
||||
signsai = -1;
|
||||
else
|
||||
signsai = 1;
|
||||
}
|
||||
print(str.substr(signsai * 6 + 6, 6) + " ");
|
||||
if (sa[i] == 0)
|
||||
print(" ");
|
||||
else
|
||||
print(" " + Math.abs(sa[i]) + " ");
|
||||
ta[i] = ta[i] + sa[i];
|
||||
print("TOTAL= " + ta[i] + "\n");
|
||||
discard_row(i);
|
||||
ta[d1] = ta[d1] - sa[i];
|
||||
i += d1;
|
||||
discard_row(i);
|
||||
i -= d1;
|
||||
}
|
||||
print("DEALER'S TOTAL= " + ta[d1] + "\n");
|
||||
print("\n");
|
||||
discard_row(i);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user