MATLAB作业选登 2048小游戏

来源:互联网 编辑:wan玩得好手游小编更新:2024-07-28 14:50:24 人气:
又玩游戏了,2048小游戏。刚看到游戏名字,我还以为是类似24点游戏,24点游戏我感觉不是太好玩,但昨天报导的42岁当选的院士,酷爱数学,他从小就喜欢二十四点游戏,他几乎是一拿到牌,看一下就能算出24来,八九岁时,他就能赢过一般的大人,以至于一些小伙伴都不愿意和他玩这个游戏。今天介绍的2048小游戏我感觉挺好玩,我玩了一下午,以下是成绩,分数5028,移动339步,最大值512。matlab也可以写面向对象的代码,首先表现在可以定义类,以及可以继承。使用类(class)有很多好处,其中一个重要的好处便是解决变量名冲突和让函数、对象的结构清晰。class的static function可以在不定义类的实例直接调用类的成员函数。


一、程序介绍

1.帮忙文件
此次作业用MATLAB实现了一个2048小游戏。
规则:开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4;玩家可以选择上下左右四个方向(方向键),若棋盘内的数字出现位移或合并,视为有效移动;玩家选择的方向上若有相同的数字则合并,每次有效移动可以同时合并,但不可以连续合并;合并所得的所有新生成数字相加即为该步的有效得分;玩家选择的方向行或列前方有空格则出现位移;每有效移动一步,棋盘的空位(无数字处)随机出现一个数字(依然可能为2或4);棋盘被数字填满,无法进行有效移动,判负,游戏结束;棋盘上出现2048,判胜,游戏结束。

71115304 邓雨田

2.程序运行后界面


3.玩游戏中......,右侧窗口记录分数增长历史


二、主程序代码及子函数

1.主程序(start2048.m)

function start2048()

handles = initFigure();

field = Field(4);

draw(handles, field, 1);

set(handles.figure, 'UserData', field, ...

         'WindowKeyPressFcn', {@keyPress, handles});

     


2.界面设计(initFigure.m)

function handles = initFigure()

set(0, 'Units', 'Pixels');

screen = get(0, 'ScreenSize');

scw = screen(3);

sch = screen(4);


width = 0.6 * scw;

sideMargin = 0.02 * width;

axWidth = (width - 3 * sideMargin) / 2;

axHeight = axWidth;


topMargin = 2 * sideMargin;

bottomMargin = sideMargin;

height = axHeight + topMargin + bottomMargin;


windowPosx = (scw - width) / 2;

windowPosy = (sch - height) / 2;


fig = figure('Name', '2048', ...

    'Menubar', 'none', ...

    'Toolbar', 'none', ...

    'NumberTitle', 'off', ...

    'Resize', 'off', ...

    'Tag', 'mainwindow', ...

    'Position', [windowPosx, windowPosy, width, height]);


ax1 = axes('Parent', fig, ...

    'Units', 'pixels', ...

    'Position', [sideMargin, bottomMargin, axWidth, axHeight], ...

    'Units', 'normalized', ...

    'Visible', 'on', ...

    'Tag', 'mainaxes', ...

    'XTickLabel', [], ...

    'YTickLabel', [], ...

    'XTick', [], ...

    'YTick', [], ...

    'Color', [252, 255, 222]/255);


ax2 = axes('Parent', fig, ...

    'Units', 'pixels', ...

    'Position', [2 * sideMargin + axWidth, bottomMargin, axWidth, axHeight], ...

    'Units', 'normalized', ...

    'Visible', 'on', ...

    'Tag', 'mainaxes', ...

    'XTickLabel', [], ...

    'YTickLabel', [], ...

    'XTick', [], ...

    'YTick', [], ...

    'Color', [252, 255, 222]/255);


boxWidth = 200;

boxHeight = 0.8 * topMargin;

scoreBox = uicontrol('style', 'edit', ...

    'Enable', 'inactive', ...

    'Parent', fig, ...

    'Units', 'pixels', ...

    'Position', [sideMargin + (axWidth - boxWidth) / 2, height - (topMargin + boxHeight) / 2, boxWidth, boxHeight], ...

    'String', 'Score: 0', ...

    'BackGroundColor', get(fig, 'Color'),...

    'FontSize', 12, 'FontWeight', 'bold');


moveBox  = uicontrol('style', 'edit', ...

    'Enable', 'inactive', ...

    'Parent', fig, ...

    'Units', 'pixels', ...

    'Position', [2 * sideMargin + (3 * axWidth - boxWidth) / 2, height - (topMargin + boxHeight) / 2, boxWidth, boxHeight], ...

    'String', 'Moves: 0', ...

    'BackGroundColor', get(fig, 'Color'),...

    'FontSize', 12, 'FontWeight', 'bold');


handles = struct('figure', fig, ...

    'field', ax1, ...

    'graph', ax2, ...

    'scoreBox', scoreBox, ...

    'moveBox', moveBox);


3.类(Field.m)

classdef Field

    properties(GetAccess = 'public', SetAccess = 'private')

        mat;

        n;

        lost = false;

        won = false;

        score = 0;

        scoreHistory = 0;

        moves = 0;

        changed = true;

    end

    

    methods(Access = 'public')

        function obj = Field(n)

            if nargin == 0

                n = 4;

            end

            i = zeros(1,2);

            while i(1) == i(2)

                i = randi(n^2, 1, 2);

            end

            

            obj.mat = zeros(n);

            obj.mat(i) = 2;

            obj.n = n;

        end

        

        function show(obj)

            disp(obj.mat);

        end

        

        function obj = move(obj, dir)

            if ~any('LRUD' == dir)

                return

            end

            

            if ~(obj.lost || obj.won)

                [obj, obj.changed] = collapse(obj, dir);

                if obj.changed

                    obj.moves = obj.moves + 1;

                    obj = insertRandom(obj);

                    obj.won = max(obj.mat(:)) == 2048;

                end

                

                obj = checkForPossibleMoves(obj);

            end

        end

    end

    

    methods(Access = 'private')

        function [obj, succes] = collapse(obj, dir)

            succes = 0;

            for i = 1:obj.n

                switch dir

                    case 'L'

                        [vec, sc, effect] = Field.merge(obj.mat(i,:));

                        obj.mat(i,:) = vec;

                    case 'R'

                        [vec, sc, effect] = Field.merge(fliplr(obj.mat(i,:)));

                        vec = fliplr(vec);

                        obj.mat(i,:) = vec;

                    case 'U'

                        [vec, sc, effect] = Field.merge(obj.mat(:,i));

                        obj.mat(:,i) = vec;

                    case 'D'

                        [vec, sc, effect] = Field.merge(flipud(obj.mat(:,i)));

                        vec = flipud(vec);

                        obj.mat(:,i) = vec;

                    otherwise

                        return;

                end

                obj.score = obj.score + sc;

                obj.scoreHistory = [obj.scoreHistory, obj.score];

                succes = succes + effect;

            end

        end

        

        function obj = insertRandom(obj)

            cand = find(~obj.mat);

            i = randi(numel(cand));

            if rand()

                value = 2;

            else

                value = 4;

            end

            obj.mat(cand(i)) = value;

        end

        

        function obj = checkForPossibleMoves(obj)

            copy = obj;

            allMoves = 'LRUD';

            for m = allMoves

                [~, succes] = collapse(copy, m);

                if succes

                    return

                end

            end

            obj.lost = true;

        end

    end

    

    methods(Access = 'public', Static = true)

        function [vec, sc, effect] = merge(vec)

            effect = 0;

            sc = 0;

            m = numel(vec);

            action = zeros(size(vec));

            for i = 2:m

                if ~vec(i)

                    continue

                end

                

                j = find(vec(1:i-1), 1, 'last'); % first nonzero left of i

                x = vec(i);

                y = vec(j);

                vec(i) = 0;

                if isempty(j) % move all the way to the edge

                    vec(1) = x;

                    effect = 1;

                elseif x == y && ~action(j) % merge them -> mark action

                    vec(j) = 2 * x;

                    action(j) = 1;

                    sc = sc + 2 * x;

                    effect = 1;

                else

                    vec(j + 1) = x;

                    if j + 1 ~= i

                        effect = 1;

                    end

                end

            end

        end

    end

end


4.绘图(draw.m)

function draw(handles, field, drawgrid)

axes(handles.field)

%% GRID

n = size(field.mat, 1);

xlm = get(handles.field, 'XLim');

ylm = get(handles.field, 'YLim');


xwidth = diff(xlm) / n;

ywidth = diff(ylm) / n;


if isempty(get(handles.field, 'UserData'))

    patches = zeros(n);

else

    patches = get(handles.field, 'UserData');

end


if drawgrid

    delete(findobj('type', 'patch', 'Parent', handles.field));

    for i = 1:n

        for j = 1:n

            x = [j - 1, j, j, j - 1] * xwidth;

            y = ylm(2) - [i - 1, i - 1, i, i] * ywidth;

            patches(i,j) = patch(x, y, 0);

        end

    end

    set(handles.field, 'UserData', patches);

end


%% NUMBERS

delete(findobj('type', 'text', 'Parent', handles.field));

cmap = [0.3686    0.3098    0.6353;

    0.1961    0.5333    0.7412;

    0.4000    0.7608    0.6471;

    0.6706    0.8667    0.6431;

    0.9020    0.9608    0.5961;

    0.9500    0.9500    0.7116;

    0.9961    0.8784    0.5451;

    0.9922    0.6824    0.3804;

    0.9569    0.4275    0.2627;

    0.8353    0.2431    0.3098;

    0.6196    0.0039    0.2588];


for i = 1:n

    for j = 1:n

        x = (j - 1 + 1/2) * xwidth;

        y = ylm(2) - (i - 1 + 1/2) * ywidth;

        value = field.mat(i,j);

        if value

            index = min(11, log(value) / log(2));

            text(x,y, num2str(value), ...

                'FontSize', 14, ...

                'FontWeight', 'bold', ...

                'Color', 'white', ...

                'HorizontalAlignment', 'Center');

            set(patches(i,j), 'FaceColor', cmap(index, :))

        else

            set(patches(i,j), 'FaceColor', [1 1 1]);

        end

    end

end



%% SCORE

set(handles.scoreBox, 'String', sprintf('Score: %d', field.score));

set(handles.moveBox, 'String', sprintf('Moves: %d', field.moves));


%% GRAPH

axes(handles.graph)

plot(field.scoreHistory)

set(handles.graph, 'XTickLabel', [], 'YTickLabel', [], 'XTick', [], 'YTick', [])


5.键盘响应(keyPress.m)

function keyPress(fig, event, handles)

dir = upper(event.Key(1));

field = get(handles.figure, 'UserData');

field = field.move(dir);


if ~field.changed

    return

end


set(handles.figure, 'UserData', field);

draw(handles, field, 0);


if field.won

    uiwait(msgbox('You Won!!'));

    close(fig);

elseif field.lost

    uiwait(msgbox('You Lost!!'));

    close(fig)

end



欢迎玩家到【wan玩得好手游】查看最新变态版手游攻略,只需要在百度输入【wan玩得好手游】就可以浏览最新上线送满vip的变态手游攻略了,更多有关BT手游的攻略和资讯,敬请关注玩得好手游!

更多...

热门推荐

更多...

相关文章