Data update

This commit is contained in:
Ingy döt Net 2025-06-11 20:16:52 -04:00
parent 72eb4943cb
commit 4d5544505c
2347 changed files with 62432 additions and 16731 deletions

View file

@ -15,7 +15,7 @@ Spawn←{i←•rand.Range∘≠⊸⊑(0⊸= /○⥊ ↕∘≢)𝕩 ⋄ (•rand
LoseLeftRightDownUp # Losing condition, no moves change the board
Win´·˝2048= # Winning condition, 2048!
Quit{•Out e"[?12l"e"[?25h" •Exit 𝕩} # Restores the terminal and exits
Quit{•Out e"[?12l"e"[?25h" •term.RawMode 0 •Exit 𝕩} # Restores the terminal and exits
Display{ # Displays the board, score and controls
•Out e"[H"e"[2J" # Cursor to origin and clear screen
•Out "Controls: h: left, j: down, k: up, l: right, q: quit"

View file

@ -0,0 +1,161 @@
len brd[] 16
gbackground 987
proc newtile .
for i to 16 : if brd[i] = 0 : break 1
if i > 16 : return
v = 2
if randomf < 0.1 : v = 4
repeat
ind = random 16
until brd[ind] = 0
.
brd[ind] = v
.
global pts stat .
proc show .
gclear
gtextsize 5
gcolor 222
gtext 10 94 "2048 Game"
gtext 60 94 "Pts: " & pts
gtextsize 7
gcolor 876
grect 9 9 82 82
gcolor 987
grect 10 10 80 80
for i to 16 : if brd[i] <> 0
x = i mod1 4 * 20 - 9.5
y = i div1 4 * 20 - 9.5
gcolor 765
grect x y 19 19
v = brd[i]
h = 2 * floor log10 v
gcolor 000
gtext x + 7 - h y + 7 brd[i]
.
.
proc init .
for i to 16 : brd[i] = 0
newtile
newtile
stat = 0
pts = 0
show
.
init
#
dir[] = [ -4 -1 4 1 ]
start[] = [ 16 4 1 13 ]
proc domove indk test &moved .
moved = 0
dir = dir[indk]
bdir = dir[(indk + 1) mod1 4]
start = start[indk]
for i to 4
h0 = start + dir
for j to 3
if brd[h0] <> 0
v = brd[h0]
h = h0
while h <> start and brd[h - dir] = 0 : h -= dir
if h <> h0
moved = 1
if test = 1 : return
.
if h <> start and brd[h - dir] = v
moved = 1
if test = 1 : return
v *= 2
pts += v
brd[h - dir] = -v
if v = 2048 : stat = 1
v = 0
.
brd[h0] = 0
brd[h] = v
.
h0 += dir
.
h0 = start
for j to 3
brd[h0] = abs brd[h0]
h0 += dir
.
sleep 0.1
show
start += bdir
.
.
proc handle indk .
if indk = 0 : return
domove indk 0 moved
if moved = 1
newtile
sleep 0.2
show
if stat = 0
stat = 2
for indk to 4
domove indk 1 moved
if moved = 1
stat = 0
break 1
.
.
.
.
if stat <> 0
gtextsize 5
if stat = 1
stat = 0
gtext 10 3 "You got 2048 😊"
else
gtext 10 3 "No more moves 🙁"
.
.
.
on mouse_down
mx = mouse_x
my = mouse_y
.
proc handle_mup .
dx = mouse_x - mx
dy = mouse_y - my
indk = 0
if abs dx > abs dy
if abs dx > 3
indk = 4
if dx > 0 : indk = 2
.
else
if abs dy > 3
indk = 3
if dy > 0 : indk = 1
.
.
if indk <> 0 and stat = 2
init
else
handle indk
.
.
on mouse_up
handle_mup
.
on key
if stat = 2
if keybkey = " " : init
return
.
indk = 0
if keybkey = "ArrowUp"
indk = 1
elif keybkey = "ArrowRight"
indk = 2
elif keybkey = "ArrowDown"
indk = 3
elif keybkey = "ArrowLeft"
indk = 4
.
handle indk
.

228
Task/2048/Zig/2048.zig Normal file
View file

@ -0,0 +1,228 @@
const std = @import("std");
const io = std.io;
const Random = std.Random;
// UserMove enum representing possible moves
const UserMove = enum {
Up,
Down,
Left,
Right,
};
// Game field type
const Field = [4][4]u32;
// Function to print the current game state
fn printGame(field: *const Field) void {
for (field) |row| {
std.debug.print("{any}\n", .{row});
}
}
// Function to get a user move
fn getUserMove() !UserMove {
const stdin = std.io.getStdIn().reader();
var buf: [2]u8 = undefined; // Buffer for input (character + newline)
while (true) {
const bytesRead = try stdin.read(&buf);
if (bytesRead < 1) continue;
switch (buf[0]) {
'a' => return UserMove.Left,
'w' => return UserMove.Up,
's' => return UserMove.Down,
'd' => return UserMove.Right,
else => {
std.debug.print("input was {c}: invalid character should be a,s,w or d\n", .{buf[0]});
},
}
}
}
// This function implements user moves.
// For every element, it checks if the element is zero.
// If the element is zero, it looks against the direction of movement if any
// element is not zero, then moves it to its place and checks for a matching element.
// If the element is not zero, it looks for a match. If no match is found,
// it looks for the next element.
fn doGameStep(step: UserMove, field: *Field) void {
switch (step) {
.Left => {
for (field) |*row| {
for (0..4) |col| {
for ((col + 1)..4) |my_testCol| {
if (row[my_testCol] != 0) {
if (row[col] == 0) {
row[col] += row[my_testCol];
row[my_testCol] = 0;
} else if (row[col] == row[my_testCol]) {
row[col] += row[my_testCol];
row[my_testCol] = 0;
break;
} else {
break;
}
}
}
}
}
},
.Right => {
for (field) |*row| {
var col: i32 = 3;
while (col >= 0) : (col -= 1) {
var my_testCol: i32 = col - 1;
while (my_testCol >= 0) : (my_testCol -= 1) {
if (row[@intCast(my_testCol)] != 0) {
if (row[@intCast(col)] == 0) {
row[@intCast(col)] += row[@intCast(my_testCol)];
row[@intCast(my_testCol)] = 0;
} else if (row[@intCast(col)] == row[@intCast(my_testCol)]) {
row[@intCast(col)] += row[@intCast(my_testCol)];
row[@intCast(my_testCol)] = 0;
break;
} else {
break;
}
}
}
}
}
},
.Down => {
for (0..4) |col_idx| {
const col = col_idx; // Convert to immutable
var row: i32 = 3;
while (row >= 0) : (row -= 1) {
var my_testRow: i32 = row - 1;
while (my_testRow >= 0) : (my_testRow -= 1) {
if (field[@intCast(my_testRow)][col] != 0) {
if (field[@intCast(row)][col] == 0) {
field[@intCast(row)][col] += field[@intCast(my_testRow)][col];
field[@intCast(my_testRow)][col] = 0;
} else if (field[@intCast(row)][col] == field[@intCast(my_testRow)][col]) {
field[@intCast(row)][col] += field[@intCast(my_testRow)][col];
field[@intCast(my_testRow)][col] = 0;
break;
} else {
break;
}
}
}
}
}
},
.Up => {
for (0..4) |col| {
for (0..4) |row| {
for ((row + 1)..4) |my_testRow| {
if (field[my_testRow][col] != 0) {
if (field[row][col] == 0) {
field[row][col] += field[my_testRow][col];
field[my_testRow][col] = 0;
} else if (field[row][col] == field[my_testRow][col]) {
field[row][col] += field[my_testRow][col];
field[my_testRow][col] = 0;
break;
} else {
break;
}
}
}
}
}
},
}
}
// Spawn a new number (2 or 4) in a random empty cell
fn spawn(field: *Field, random: Random) void {
while (true) {
const x = random.uintLessThan(usize, 16); // Random position 0-15
const row = x % 4;
const col = (x / 4) % 4;
if (field[row][col] == 0) {
// 10% chance for a 4, 90% chance for a 2
if (random.uintLessThan(usize, 10) == 0) {
field[row][col] = 4;
} else {
field[row][col] = 2;
}
break;
}
}
}
// Check if fields are equal
fn areFieldsEqual(a: *const Field, b: *const Field) bool {
for (0..4) |i| {
for (0..4) |j| {
if (a[i][j] != b[i][j]) return false;
}
}
return true;
}
// Check if player has won (any tile equals 2048)
fn checkWin(field: *const Field) bool {
for (field) |row| {
for (row) |cell| {
if (cell == 2048) return true;
}
}
return false;
}
pub fn main() !void {
var prng = std.Random.DefaultPrng.init(@intCast(std.time.milliTimestamp()));
const random = prng.random();
var field: Field = [_][4]u32{[_]u32{0} ** 4} ** 4;
var my_test: Field = undefined;
gameLoop: while (true) {
// Check if there's still an open space
@memcpy(&my_test, &field);
spawn(&field, random);
// Check if any valid moves remain
var validMoveExists = false;
const moves = [_]UserMove{ .Up, .Down, .Left, .Right };
for (moves) |move| {
@memcpy(&my_test, &field);
doGameStep(move, &my_test);
if (!areFieldsEqual(&my_test, &field)) {
validMoveExists = true;
break;
}
}
if (!validMoveExists) {
std.debug.print("No more valid moves, you lose\n", .{});
break :gameLoop;
}
// Print the current game state
printGame(&field);
std.debug.print("move the blocks\n", .{});
// Get and apply user move
@memcpy(&my_test, &field);
while (areFieldsEqual(&my_test, &field)) {
const move = try getUserMove();
doGameStep(move, &field);
}
// Check win condition
if (checkWin(&field)) {
printGame(&field);
std.debug.print("You Won!!\n", .{});
break :gameLoop;
}
}
}