24 game: Difference between revisions

8,389 bytes added ,  22 days ago
fix syntax highlighting
(fix syntax highlighting)
 
(16 intermediate revisions by 3 users not shown)
Line 5,835:
¿Otra ronda? (Pulsa S para salir, u otra tecla para continuar)
 
</pre>
 
=={{header|Frink}}==
<syntaxhighlight lang="frink">ops = ["+", "-", "*", "/"]
 
chosen = new array[[4], {|x| random[1,9]}]
println[chosen]
 
for d = chosen.lexicographicPermute[]
multifor o = [ops, ops, ops]
{
str = "((" + d@0 + o@0 + d@1 + ")" + o@1 + d@2 + ")" + o@2 + d@3
if eval[str] == 24
println[str]
str = "(" + d@0 + o@0 + d@1 + ")" + o@1 + "(" + d@2 + + o@2 + d@3 + ")"
if eval[str] == 24
println[str]
}</syntaxhighlight>
{{out}}
<pre>
[9, 8, 7, 4]
(4+8)*(9-7)
((7+8)-9)*4
((7-9)+8)*4
(8+4)*(9-7)
((8+7)-9)*4
((8-9)+7)*4
(8*9)/(7-4)
(9-7)*(4+8)
(9-7)*(8+4)
(9*8)/(7-4)
</pre>
 
=={{header|FutureBasic}}==
24 Game
May 12, 2024
Updated game rules
Rich Love
<syntaxhighlight lang="futurebasic">
// 24 Game
// May 12, 2024 Rich Love
 
May 17, 2024
 
Rich Love
 
Thanks to Ken and Bernie
<syntaxhighlight lang="futurebasic">
#build CompilerOptions @"-Wno-unused-variable"
 
Line 5,858 ⟶ 5,889:
end fn
 
local fn ArcRandom( a as long, b as long ) as long
long i
cln i = (arc4random()%(b-a+1))+a;
end fn = fn floor(i)
 
local fn GetRandomNumbers as CFStringRef
CFArrayRef combos = @[¬
@"1 3 2 6", @"1 7 2 1", @"1 5 2 2", @"1 9 2 1", @"3 7 6 2",¬
@"1 2 3 9", @"1 6 3 1", @"1 4 3 3", @"1 4 5 6", @"1 3 4 4",¬
@"1 1 6 2", @"1 9 3 1", @"2 2 3 2", @"2 7 3 2", @"6 4 9 8",¬
@"2 8 2 1", @"3 2 5 2", @"6 5 4 4", @"2 6 6 8", @"2 4 3 1",¬
@"2 8 1 1", @"2 7 8 2", @"3 9 6 2", @"3 5 2 1", @"3 3 2 2",¬
@"3 7 1 1", @"3 8 9 3", @"2 5 7 8", @"3 8 1 6", @"4 2 9 1",¬
@"4 4 2 1", @"4 8 1 1", @"8 8 9 6", @"4 6 1 1", @"5 6 8 5",¬
@"5 7 1 1", @"5 8 9 5", @"8 6 4 2", @"5 2 2 2", @"5 4 1 1",¬
@"2 5 8 2", @"3 4 3 3", @"6 6 2 1", @"6 7 8 9", @"6 1 4 8",¬
@"4 6 9 4", @"9 5 5 9", @"7 5 6 5", @"7 4 9 4", @"8 1 8 6",¬
@"7 1 2 2", @"7 3 4 1", @"7 4 1 1", @"7 8 8 9", @"8 4 2 1",¬
@"4 5 7 9", @"7 3 3 3", @"9 3 2 7", @"2 3 5 3", @"9 7 4 2",¬
@"9 1 8 3", @"9 2 4 3", @"9 4 1 3", @"4 7 8 2", @"1 8 6 2",¬
@"6 1 6 1", @"3 5 6 8", @"1 8 3 1", @"5 7 1 3", @"6 2 3 4",¬
@"5 5 6 1", @"2 6 1 2", @"8 1 2 9", @"4 9 6 1", @"6 4 1 2",¬
@"4 7 3 2", @"5 5 4 9", @"9 2 7 1", @"5 5 6 3", @"6 2 4 2",¬
@"9 4 3 7", @"1 5 7 6", @"5 3 4 7", @"1 1 3 5", @"1 4 5 2",¬
@"1 3 8 2", @"1 5 6 2", @"1 5 8 1", @"2 6 7 1", @"2 3 4 2",¬
@"2 3 6 3", @"2 6 8 2", @"3 4 5 9", @"4 7 8 4", @"3 1 8 4",¬
@"2 8 8 2"]
long i = fn ArcRandom( 0, len(combos) - 1 )
end fn = combos[i]
 
 
Line 5,901 ⟶ 5,963:
 
local fn QuitOrPlayAlert(GameResult as CFStringRef)
alert -2,,GameResult,@"You won!",@"Quit;Play Again"
alert -2,,GameResult,@"Game Over",@"Quit;Play Again"
AlertButtonSetKeyEquivalent( 2, 2, @"\e" )
short result
result = alert 2
if ( result != NSAlertSecondButtonReturn ) then appterminate
end fn
 
 
local fn BuildWindow
CGRect r = fn CGRectMake( 0, 0, 580, 250)
window 1, @"24 Game", r
Line 5,919 ⟶ 5,978:
end fn
 
 
///////// Start //////////
 
fn BuildWindow
 
 
short d(4), i
CFStringRef CheckForDuplicates(97)
for i = 1 to 96
CheckForDuplicates(i) = @""
next i
 
short DuplicatesCounter
DuplicatesCounter = 0
 
 
Line 5,932 ⟶ 6,000:
 
print
 
print %(10,15),"Given four numbers and using just the +, -, *, and / operators; and the"
print %(10,30),"possible use of parenthesis (), enter an expression that equates to 24."
print %(10,45),"You must use all your numbers and only those numbers."
print %(10,60),"Examples: 9618 Solution 9 + 6 + 1 + 8 or 37733173 Solution ((3 * 1) * 7) + 3"
print
print %(10,85),"Enter Q to quit or S to skip to the next number."
 
"GetFourNumbers"
 
CFArrayRef randomNumbers : randomNumbers= fn StringComponentsSeparatedByString( fn GetRandomNumbers, @" " )
"GetRandomNumbers"
CFStringRef RandomNumberblock : RandomNumberblock = @""
short i
CFStringRef RandomNumberblockAdd : RandomNumberblockAdd = @""
short d(4)
 
short chk(4)
for i = 10 to 43
// create a string from the 4 numbers
d(i)= rnd(9) // digets 1..9
RandomNumberblockAdd = randomNumbers[i]
chk(i)=d(i)
RandomNumberblock = fn StringByAppendingString(RandomNumberblock,RandomNumberblockAdd)
next
RandomNumberblock = fn StringByAppendingString(RandomNumberblock,@" ")
next i
 
 
if DuplicatesCounter = > 96
// reset counter when last number is retrieved and start from the first number block
DuplicatesCounter = 0
for i = 1 to 96
CheckForDuplicates(i) = @""
next i
end if
 
for i = 1 to 96
// check the current numbers with the numbers already used
if fn StringIsEqual(RandomNumberblock,CheckForDuplicates(i))
RandomNumberblock = fn StringWithString(CheckForDuplicates(DuplicatesCounter))
goto "GetFourNumbers"
end if
next i
 
DuplicatesCounter ++
CheckForDuplicates(DuplicatesCounter) = fn StringWithString(RandomNumberblock)
 
d(1) = fn StringIntegerValue( randomNumbers[0] )
d(2) = fn StringIntegerValue( randomNumbers[1] )
d(3) = fn StringIntegerValue( randomNumbers[2] )
d(4) = fn StringIntegerValue( randomNumbers[3] )
 
//d(1) = 9:d(2) = 6:d(3) = 1:d(4) = 8 // Uncomment to test with 9618 numbers. Solution 9 + 6 + 1 + 8
Line 5,957 ⟶ 6,052:
 
print
 
text ,,fn colorGreen
print %(10,110),"These are your numbers: "
Line 5,965 ⟶ 6,059:
print d(i); " ";
next
 
print
 
text ,12,fn colorWhite
printf @"\n\n\n"
 
CFStringRef expr
print:print:print:print
bool TryAgain : TryAgain = _false
CFStringRef MessageText
CFStringRef UserInput = NULL
 
str255 expr
bool TryAgain
TryAgain = _false
str255 MessageText
CFStringRef MessageTextRef
 
CFStringRef UserInput = 0
"InputExpression"
 
if TryAgain
MessageText = fn StringWithFormat( @"Enter math expression: [ " + expr + "'%@' was incorrect ]", expr )
UserInput = input %(10, 190), MessageText, @"123456789+-*/()qs", YES,, 0
MessageTextRef = fn StringWithPascalString(MessageText)
UserInput = input % (10, 190),MessageTextRef, @"123456789+-*/()q", YES,, 0
else
UserInput = input % (10, 190), @"Enter math expression:", @"123456789+-*/()qqs", YES,, 0
end if
 
if ( UserInput == NULL ) then "InputExpression"
expr = UserInput
fn CFStringGetPascalString (UserInput, @expr, 256, _kCFStringEncodingMacRoman)
if expr = @"" then "InputExpression"
if fn StringIsEqual(ucase$(expr) =, @"Q") then appterminate
if fn StringIsEqual(ucase$(expr) =, @"XS") then appterminate"Main"
 
 
//check expr for validity
 
short j
bool GotAllNumbers : GotAllNumbers = _false
short ThisNumberPosition : ThisNumberPosition = 0
short GotaNumber : GotaNumber = 0
short TotalNumbers : TotalNumbers = 0
 
short ExtraNumbers:ExtraNumbers = 0
 
for i = 1 to len$(fn stringpascalstring(expr))
if asc(mid$(fn stringpascalstring(expr),i,1)) > 48 && asc(mid$(fn stringpascalstring(expr),i,1)) < 58
ExtraNumbers ++
end if
next i
 
if ExtraNumbers > 4
fn EraseErrorText
text ,,fn colorRed
TryAgain = _true
print %(10,200);"Error! Extra numbers not allowed": goto "InputExpression"
text ,,fn colorWhite
end if
 
bool GotAllNumbers
gotAllNumbers = _false
short ThisNumberPosition
ThisNumberPosition = 0
short j
short GotaNumber
GotaNumber = 0
short TotalNumbers
TotalNumbers = 0
 
for i = 1 to 4
GotaNumber = 0
for j = 10 to len$(expr) -1
ThisNumberPosition = instr$( j, expr, right$(str$( d(i)),1 ))
if ThisNumberPosition then GotaNumber = 1++
if ThisNumberPosition then GotaNumber = _true
next j
if GotaNumber then TotalNumbers ++
next i
 
if TotalNumbers => 4 then GotAllNumbers = _true
 
if TotalNumbers = > 4 then GotAllNumbers = _true
 
 
if GotAllNumbers = _false
Line 6,026 ⟶ 6,126:
text ,,fn colorRed
TryAgain = _true
print %(10,200);"ERROR! Must use all your numbers and only those numbers." : goto "InputExpression"
text ,,fn colorWhite
end if
 
 
fn EraseErrorText
 
 
if fn EvaluateMath( fn StringWithPascalString (expr)) = _false
if fn EvaluateMath( expr ) = _false
text ,,fn colorRed
TryAgain = _true
Line 6,041 ⟶ 6,141:
end if
 
 
CFStringRef AnswerRef
AnswerRef = fn EvaluateMath( fn StringWithPascalString (expr))
CFStringRef GameResult
if fn StringIntegerValue( fn EvaluateMath( expr ) ) == 24 then GameResult = @"Correct" else GameResult = @"Incorrect"
str255 AnswerString
AnswerString = fn StringPascalString(AnswerRef)
 
if int(val(AnswerString)) = 24 then GameResult = @"Correct" else GameResult = @"Incorrect"
 
 
if GameResult = @"Incorrect"
Line 6,058 ⟶ 6,151:
fn QuitOrPlayAlert(GameResult)
goto "Main"
 
 
handleevents
Line 6,823 ⟶ 6,915:
}
</syntaxhighlight>
 
=={{header|jq}}==
'''Works with jq, the C implementation of jq'''
 
'''Works with gojq, the Go implementation of jq'''
 
Note that the RPN evaluator used here allows expressions such as "1 2 3 + +".
 
Note also that in RPN expressions:
* If a and b are numeric, then "a b -" is evaluated to the arithmetic expression `a - b`.
* If a and b are numeric, then "a b /" is evaluated as a/b, which need not be an integer.
 
For the "24 Game":
* Spaces may be omitted in RPN input.
* When comparing a result to 24, `round` is used.
 
The [[:Category:Jq/MRG32k3a.jq | MRG32k3a]] module is used for generating pseudo-random numbers.
<syntaxhighlight lang="jq">
 
### The MRG32k3a combined recursive PRNG - see above
import "MRG32k3a" as MRG {search: "."};
 
### Generic utilities
def sum(stream): reduce stream as $x (0; .+$x);
 
# like while/2 but emit the final term rather than the first one
def whilst(cond; update):
def _whilst:
if cond then update | (., _whilst) else empty end;
_whilst;
 
### Reverse Polish Notation
# An array of the allowed operators
def operators: "+-*/" | split("");
 
# If $a and $b are numbers and $c an operator, then "$a $b $c" is evaluated as an RPN expression.
# Output: {emit, result} with .emit == null if there is a valid result.
def applyOperator($a; $b; $c):
if ([$a,$b] | map(type) | unique) == ["number"]
then
if $c == "+" then {result: ($a + $b)}
elif $c == "-" then {result: ($a - $b)}
elif $c == "*" then {result: ($a * $b)}
elif ($c == "/") then {result: ($b / $a)}
else {emit: "unrecognized operator: \($c)"}
end
else {emit: "invalid number"}
end;
 
# Input: an array representing an RPN expression.
# Output: {emit, result} as per applyOperator/3
# Example: [1,2,3,"+","+"] | evaluate #=> 6
def evaluate:
if length == 1
then if .[0]|type == "number" then {result: .[0]}
else {emit: "invalid RPN expression"}
end
elif length < 3 then {emit: "invalid RPN expression: \(. | join(" "))"}
else . as $in
| (first( range(0; length) as $i | select(any( operators[]; . == $in[$i]) ) | $i) // null) as $ix
| if $ix == null then {emit: "invalid RPN expression"}
else applyOperator(.[$ix-2]; .[$ix-1]; .[$ix]) as $result
| if $result.result then .[:$ix-2] + [$result.result] + .[$ix+1:] | evaluate
else $result
end
end
end;
 
### The "24 Game"
 
# . is the putative RPN string to be checked.
# $four is the string of the four expected digits, in order.
# Output: {emit, result} with .emit set to "Correct!" if .result == 24
def check($four):
if (gsub("[^1-9]";"") | explode | sort | implode) != $four
then {emit: "You must use each of the four digits \($four | split("") | join(" ")) exactly once:"}
else . as $in
| {s: [], emit: null}
| [$in | split("")[] | select(. != " ")
| . as $in | explode[0] | if . >= 48 and . <= 57 then . - 48 else $in end]
| evaluate
| if .result
then if .result|round == 24 then .emit = "Correct!"
else .emit = "Value \(.result) is not 24."
end
else .emit += "\nTry again, or enter . to start again, or q to quit."
end
end ;
 
def run:
# Populate .digits with four non-negative digits selected at random, with replacement:
{digits: (9 | MRG::prn(4) | map(. + 1))}
| (.digits | sort | join("")) as $four
| "At the prompt, enter an RPN string (e.g. 64*1+1-), or . for a new set of four digits, or q to quit.",
"Make 24 using these digits, once each, in any order: \(.digits):",
( whilst( .stop | not;
.emit = null
| . as $state
| try input catch halt
| if IN( "q", "quit") then halt
elif . == "." then $state | .stop = true
else check($four)
| if .result then .stop = true end
end )
| select(.emit).emit ),
# rerun
run;
 
run
</syntaxhighlight>
{{output}}
The following is an illustrative transcript.
<pre>
$ jq -nRr -f 24-game.jq
At the prompt, enter an RPN string (e.g. 64*1+1-), or . for a new set of four digits, or q to quit.
Make 24 using these digits, once each, in any order: [7,7,6,8]:
7768+++
Value 28 is not 24.
At the prompt, enter an RPN string (e.g. 64*1+1-), or . for a new set of four digits, or q to quit.
Make 24 using these digits, once each, in any order: [7,8,6,8]:
.
At the prompt, enter an RPN string (e.g. 64*1+1-), or . for a new set of four digits, or q to quit.
Make 24 using these digits, once each, in any order: [7,2,1,8]:
82*71++
Correct!
At the prompt, enter an RPN string (e.g. 64*1+1-), or . for a new set of four digits, or q to quit.
Make 24 using these digits, once each, in any order: [6,4,2,6]:
q
$
</pre>
 
=={{header|Julia}}==
Line 12,040 ⟶ 12,262:
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">import os
import rand
import rand.seed