Bingo!

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
Fabrizio_00000
Posts: 21
Joined: Mar 31, 2011 17:30
Location: Rome, Italy

Bingo!

Post by Fabrizio_00000 »

Every Christmas is the same story: we want to play bingo but either we can't find the cards or some are missing. With this little program you can print one or more random series of 6 cards. the program output will be a printable html file, located in the same directory as the executable. the quantity of series to be generated can be specified in the command line.

The program design constraints are:
* each series consists of 6 cards each of which will contain exactly 15 numbers
* each card in a series will have all numbers different from the other cards
* each card is a 3 row x 10 column grid
* exactly 5 numbers must be placed on each line
* each column can contain 1 or 2 numbers.

Code: Select all

dim as integer i, j, k, l, d2, d3, temp, a2, s(1 to 3), nptr(1 to 9), tcnt, sr, cnt
dim shared as integer tot(1 to 9) = {9, 10, 10, 10, 10, 10, 10, 10, 11}
dim shared as integer cmb(1 to 6, 1 to 84), qty(1 to 6)
dim as integer num(1 to 9, 1 to 11) = {	{ 1,  2,  3,  4,  5,  6,  7,  8,  9,  0,  0}, _
					{10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0}, _
					{20, 21, 22, 23, 24, 25, 26, 27, 28, 29,  0}, _
					{30, 31, 32, 33, 34, 35, 36, 37, 38, 39,  0}, _
					{40, 41, 42, 43, 44, 45, 46, 47, 48, 49,  0}, _
					{50, 51, 52, 53, 54, 55, 56, 57, 58, 59,  0}, _
					{60, 61, 62, 63, 64, 65, 66, 67, 68, 69,  0}, _
					{70, 71, 72, 73, 74, 75, 76, 77, 78, 79,  0}, _
					{80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90}}
dim shared as integer tmp(1 to 84) =   { 63,  95, 111, 119, 123, 125, 126, 159, 175, 183, 187, _
					189, 190, 207, 215, 219, 221, 222, 231, 235, 237, 238, _
					243, 245, 246, 249, 250, 252, 287, 303, 311, 315, 317, _
					318, 335, 343, 347, 349, 350, 359, 363, 365, 366, 371, _
					373, 374, 377, 378, 380, 399, 407, 411, 413, 414, 423, _
					427, 429, 430, 435, 437, 438, 441, 442, 444, 455, 459, _
					461, 462, 467, 469, 470, 473, 474, 476, 483, 485, 486, _
					489, 490, 492, 497, 498, 500, 504}
dim shared as integer ccmb(1 to 126) = { 31,  47,  55,  59,  61,  62,  79,  87,  91,  93,  94, _
					103, 107, 109, 110, 115, 117, 118, 121, 122, 124, 143, _
					151, 155, 157, 158, 167, 171, 173, 174, 179, 181, 182, _
					185, 186, 188, 199, 203, 205, 206, 211, 213, 214, 217, _
					218, 220, 227, 229, 230, 233, 234, 236, 241, 242, 244, _
					248, 271, 279, 283, 285, 286, 295, 299, 301, 302, 307, _
					309, 310, 313, 314, 316, 327, 331, 333, 334, 339, 341, _
					342, 345, 346, 348, 355, 357, 358, 361, 362, 364, 369, _
					370, 372, 376, 391, 395, 397, 398, 403, 405, 406, 409, _
					410, 412, 419, 421, 422, 425, 426, 428, 433, 434, 436, _
					440, 451, 453, 454, 457, 458, 460, 465, 466, 468, 472, _
					481, 482, 484, 488, 496}

function mknum(lvl as integer) as integer
dim as integer i, j, k, nums, ok
	for i = 1 to 84
		qty(lvl) = cmb(lvl, i)
		ok = true
		for k = 1 to 9
			nums = 0
			for j = 1 to lvl
				nums += iif(qty(j) and 2 ^ (k - 1), 2, 1)
			next
			if (tot(k) - nums > (6 - lvl) * 2) or _
			   (lvl < 6 and nums >= tot(k)) or _
			   (lvl = 6 and nums <> tot(k)) then
				ok = false
				exit for
			endif
		next
		if ok then
			if lvl = 6 then return true
			if mknum(lvl + 1) then return true
		endif
	next
	return false
end function

tcnt = val(command(1))
if tcnt = 0 then tcnt = 1
randomize timer
open "test.html" for output as 1
print #1, "<html><head><style>table {width: 90%;} td {width: 11%;} table, th, td " + _
	  "{border: 1px solid black; border-collapse: collapse;} th, td {padding: 7px;} " + _
	  "p { text-align: center; font-family: ""Times New Roman"", Times, serif; " + _
	  "font-size: 35px;}</style></head><body>"
for sr = 1 to tcnt
	for i = 1 to 9
		for j = 1 to tot(i)
			swap num(i, int(rnd() * tot(i) + 1)), num(i, int(rnd() * tot(i) + 1))
		next
		nptr(i) = 1
	next
	for i =	1 to 6
		for j = 1 to 84
			cmb(i, j) = tmp(j)
		next
		for j = 1 to 42
			swap cmb(i, int(rnd() * 84) + 1), cmb(i, int(rnd() * 84) + 1)
		next
	next
	mknum 1
	for i = 1 to 6
		for j = 1 to 63
			swap ccmb(int(rnd() * 126) + 1), ccmb(int(rnd() * 126) + 1)
		next
		for j = 1 to 126
			s(1) = ccmb(j)
			temp = s(1) xor 511
			d2 = temp or qty(i)
			d3 = temp and qty(i)
			for k = 1 to 126
				s(2) = ccmb(k)
				temp = d3
				if (s(2) and d2) = s(2) then
					a2 = s(2) xor d2
					d3 or= a2
					if not(d3 and a2) then
						for l = 1 to 126
							s(3) = ccmb(l)
							if (s(3) and d3) = s(3) then exit for, for, for
						next
					endif
				endif
				d3 = temp
			next
		next
		cnt += 1
		print #1, "<center><table>"
		print #1, "<tr><td colspan=""9"">"; trim(str(cnt)); "</td></tr>"
		for j = 1 to 3
			print #1, "<tr>";
			for k = 1 to 9
				print #1, "<td height=""97"">";
				if s(j) and 2 ^ (k - 1) then
					print #1, "<p><b>" + trim(str(num(k, nptr(k)))) + "</b></p>";
					nptr(k) += 1
				else
					print #1, "&nbsp;";
				endif
				print #1, "</td>";
			next
			print #1, "</tr>"
		next
		print #1, "</table></center><br/>"
		if cnt mod 3 = 0 and cnt < tcnt * 6 then print #1, "<p style=""page-break-before: always"">"
	next
next
print #1, "</center></body></html>"
Laurens
Posts: 17
Joined: Mar 16, 2022 9:16
Location: Flevoland, the Netherlands

Re: Bingo!

Post by Laurens »

In our country we got bingo cards of 5x5, numbered from 1-15, 16-31, until 75 is reached at the O. Here's a local variant also writing html files, for those who use the same type of cards. I used Geany as IDE.

Code: Select all


'First prepare the random items per column:
Dim As String 	Hh,			Th,			Td1,		Td2, 		Td3, 		Tb, 		Hb
Dim As Integer 	Crt(5, 5), 	TmpInt0, 	TmpInt1, 	TmpInt2, 	TmpInt3
Dim Shared As Integer 		Items (5)
Randomize

'This is a modification to Random numbers without repeating a value, generating 5 values between 1 and 15 in ascending order.
'https://rosettacode.org/wiki/Generate_random_numbers_without_repeating_a_value#FreeBASIC
Sub pRand ()
    Dim As Integer RandCheck(15), TmpInt, Act = 1
	Dim As Boolean Swapped
    Do
        Dim As Integer aleat = Int(Rnd * 15) + 1
        If RandCheck(aleat) = 1 Then
            Continue Do
        Else
            RandCheck(aleat) = 1
			Items (Act) = aleat
			Act += 1
        End If
    Loop Until Act > 5
    
    Do
		Swapped = False
		For TmpInt = 1 To 4
			If Items (TmpInt) > Items (TmpInt + 1) Then
				Swap Items (TmpInt), Items (TmpInt + 1)
				Swapped = True
			End If
		Next TmpInt
	Loop Until Swapped = False
    
End Sub

'Creating HTML document:
Hh =	"<!DOCTYPE html>" & Chr(10) & "<html><head></head>" & Chr(10) & "<body><h1 style=""text-align:center"">Bingo!</h1>"
Th =	"<table style='font-family: 'Courier New', Courier, monospace; font-size:80%' border = 1 cellpadding = 10 cellspacing = 0 bgcolor = #ddffff>" &_
		"<tbody><tr bgcolor = #00ffff><td align=center> <b>B</b> </td><td align=center> <b>I</b> </td><td align=center> <b>N</b> </td><td align=center> <b>G</b>" &_
		"</td><td align=center> <b>O</b> </td></tr>"
Td1 = 	"<tr><td align=center>"
Td2 = 	"</td><td align=center>"
Td3 = 	"</td></tr>"
Tb =	"</tbody>" & Chr(10) & "</table>"
Hb =	Chr(10) & "</body></html>"

Open "bingo.html" For Output As #1
'Save Html headers to file:
Print #1, Hh

'Create table - in - table

Print #1, "<table Border = 0>"

For TmpInt3 = 1 To 4 'number of rows
	Print #1, "<tr>"
	For TmpInt2 = 1 To 4 'number of columns
		Print #1, "<td>"

		'Create numbers in this table:
		For TmpInt1 = 1 To 5
			pRand
			For TmpInt0 = 1 To 5
				Crt (TmpInt1, TmpInt0) = Items(TmpInt0) + ((TmpInt1 - 1) * 15)
			Next TmpInt0
		Next TmpInt1

		'Save table to file:
		Print #1, Th
		Print #1, Td1; Crt (1, 1); Td2; Crt (2, 1); Td2; Crt (3, 1); Td2; Crt (4, 1); Td2; Crt (5, 1); Td3
		Print #1, Td1; Crt (1, 2); Td2; Crt (2, 2); Td2; Crt (3, 2); Td2; Crt (4, 2); Td2; Crt (5, 2); Td3
		Print #1, Td1; Crt (1, 3); Td2; Crt (2, 3); Td2; Crt (3, 3); Td2; Crt (4, 3); Td2; Crt (5, 3); Td3
		Print #1, Td1; Crt (1, 4); Td2; Crt (2, 4); Td2; Crt (3, 4); Td2; Crt (4, 4); Td2; Crt (5, 4); Td3
		Print #1, Td1; Crt (1, 5); Td2; Crt (2, 5); Td2; Crt (3, 5); Td2; Crt (4, 5); Td2; Crt (5, 5); Td3
		Print #1, Tb

		If TmpInt2 < 4 Then Print #1, "</td><td>&nbsp;"
		Print #1, "</td>"
	Next TmpInt2
	Print #1, "</tr>"
Next TmpInt3
Print #1, "</table>"

'Save Html bottom to file:
Print #1, Hb
Close #1

Print "File bingo.html written."
Print
Post Reply