实现经典的 2048 游戏,需要用到 Matlab GUI (图形用户界面)工具箱中的按钮、文本框和坐标轴等控件。这里提供一个简易版本的代码,不含动画效果和图形界面美化。
function play2048()
% 初始化游戏界面
board = zeros(4, 4);
newNumber = addNewNumber(board);
newNumber = addNewNumber(newNumber);
updateBoard(newNumber);
% 监听键盘事件
f = figure('KeyPressFcn', @keyPressedCallback, 'Name', '2048 Game');
function keyPressedCallback(~, event)
switch event.Key
case 'uparrow'
[newBoard, score] = moveUp(board);
case 'downarrow'
[newBoard, score] = moveDown(board);
case 'leftarrow'
[newBoard, score] = moveLeft(board);
case 'rightarrow'
[newBoard, score] = moveRight(board);
otherwise
return;
end
if ~isequal(newBoard, board)
newBoard = addNewNumber(newBoard);
updateBoard(newBoard, score);
board = newBoard;
if isGameOver(board)
msgbox('Game Over!', '2048 Game', 'warn');
end
end
end
function updateBoard(board, score)
clf;
ax = axes(f);
set(ax, 'XTick', [], 'YTick', [], 'XLim', [0.5 4.5], 'YLim', [0.5 4.5], ...
'DataAspectRatio', [1 1 1], 'XColor', 'w', 'YColor', 'w', 'Color', 'k');
if nargin == 2
title(ax, sprintf('2048 Game (Score: %d)', score), 'Color', 'w');
else
title(ax, '2048 Game', 'Color', 'w');
end
for row = 1:4
for col = 1:4
rectangle(ax, 'Position', [col-1 row-1 1 1], 'FaceColor', getColor(board(row, col)));
if board(row, col) > 0
text(ax, col - 0.5, row - 0.5, num2str(board(row, col)), ...
'HorizontalAlignment', 'center', 'VerticalAlignment', 'middle', 'Color', 'w');
end
end
end
drawnow;
end
function color = getColor(num)
switch num
case 0
color = [0.5 0.5 0.5];
case 2
color = [0.9294 0.8784 0.7882];
case 4
color = [0.9294 0.8275 0.6392];
case 8
color = [0.9529 0.6902 0.3804];
case 16
color = [0.9373 0.4902 0.2745];
case 32
color = [0.9020 0.3019 0.1490];
case 64
color = [0.8510 0.2078 0.1569];
case 128
color = [0.9020 0.5608 0.2157];
case 256
color = [0.9333 0.7255 0.3137];
case 512
color = [0.9412 0.8667 0.4275];
case 1024
color = [0.9490 0.9098 0.5804];
case 2048
color = [0.9490 0.9098 0.3686];
otherwise
color = [1 1 1];
end
end
function [newBoard, score] = moveUp(board)
newBoard = flipud(board);
[newBoard, score] = moveLeft(newBoard);
newBoard = flipud(newBoard);
end
function [newBoard, score] = moveDown(board)
newBoard = flipud(board);
[newBoard, score] = moveRight(newBoard);
newBoard = flipud(newBoard);
end
function [newBoard, score] = moveLeft(board)
newBoard = zeros(4, 4);
score = 0;
for row = 1:4
merged = false;
colNew = 1;
for col = 1:4
if board(row, col) > 0
if colNew > 1 && ~merged && newBoard(row, colNew-1) == board(row, col)
% 合并相邻的数字
newBoard(row, colNew-1) = 2 * board(row, col);
score = score + newBoard(row, colNew-1);
merged = true;
else
% 移动数字
newBoard(row, colNew) = board(row, col);
colNew = colNew + 1;
merged = false;
end
end
end
end
end
function [newBoard, score] = moveRight(board)
newBoard = flipud(board);
[newBoard, score] = moveLeft(newBoard);
newBoard = flipud(newBoard);
end
function newBoard = addNewNumber(board)
% 找到空闲位置
[rows, cols] = find(board == 0);
if isempty(rows)
newBoard = board;
return;
end
% 随机选择一个空闲位置放置新数字
idx = randi(length(rows));
row = rows(idx);
col = cols(idx);
% 90%几率出现2,10%几率出现4
if rand() < 0.9
newNumber = 2;
else
newNumber = 4;
end
board(row, col) = newNumber;
newBoard = board;
end
function gameOver = isGameOver(board)
[rows, cols] = find(board == 0);
if ~isempty(rows)
gameOver = false;
return;
end
% 判断每个数字是否能与其相邻的数字合并或移动
for row = 1:4
for col = 1:4
n = board(row, col);
if row > 1 && board(row-1, col) == n
gameOver = false;
return;
end
if row < 4 && board(row+1, col) == n
gameOver = false;
return;
end
if col > 1 && board(row, col-1) == n
gameOver = false;
return;
end
if col < 4 && board(row, col+1) == n
gameOver = false;
return;
end
end
end
gameOver = true;
end
end
运行上述代码后,会生成一个带有坐标轴的窗口,用于显示游戏界面和得分。在窗口中按键盘上、下、左、右方向键即可移动数字块。当没有空余的位置或者所有数字都不能再合并或移动时,游戏结束。在此版本中,当游戏结束时会弹出消息框提示。