Files
basic-computer-games/10_Blackjack/javascript/blackjack.js
Martin Thoma e64fb6795c MAINT: Apply pre-commit
Remove byte-order-marker pre-commit check as there would be
many adjustments necessary
2022-03-05 09:29:23 +01:00

550 lines
16 KiB
JavaScript

// 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();