在计算机上复现童年的一个游戏棋,为其取名为“以多胜少”

本文描述了一个基于MVC模式的游戏设计,名为以多胜少,规则涉及棋子在棋盘上的移动和吃子判定。文章详细介绍了棋子类、控制器类和视图类的功能,以及游戏规则和MVC模式在游戏开发中的应用。
摘要由CSDN通过智能技术生成

我记忆中,规则很简单,你我双方两种棋子(如黑、白),若在一条直线上(横或竖),形成“黑黑白”“黑黑黑白白”或“白白白黑”等以多对少的局面,则数目多的棋子可以“吃掉”数目少的。

我记得这游戏是双方各执7个棋子,但是按照程序员一贯的作风,棋盘的规模须能让人自由选择。我还记得“吃掉”棋子后得继续玩,直到一方失去所有的棋子才结束,可是我思索,这游戏的核心就是棋子数量,如果某一方棋子数量减少,那么他很难翻盘,干脆修改胜负规则为:一旦失去棋子就结束,不用再玩了。我记不清是否有斜线上的判定,而且这个代码可能很麻烦,姑且放下它。

那时我上小学,这棋是同村小我两三岁的人告诉我的。我记得他介绍了这个棋,却没说它的名字,那么我权且叫它“以多胜少”吧。

class PieceModel:

    '''棋子的方位,编号'''

    def __init__(self,x=0,y=0,id=0) -> None:

        self.x=x

        self.y=y

        self.id=id

class Controller:

    '''棋子的移动,上下左右;

    判断吃子与否'''

    def __init__(self) -> None:

        #棋子的列表、矩阵

        self.piece_list=[]

        self.piece_matrix=[]

        self.me_piece_data=[]

        self.you_piece_data=[]

    __Me_id=0

    __You_id=100

    def create_board(self,scale):

        #创建棋盘,scale规模

        if Controller.__Me_id:

            Controller.__Me_id=0

        if Controller.__You_id!=100:

            Controller.__You_id=100

        for i in range(scale):

            for j in range(scale):

                if i==0 or i==scale-1:

                    self.piece_list.append(self.create_piece(i,j))

                    if i==0:

                        self.you_piece_data.append(self.piece_list[j])

                    else:

                        self.me_piece_data.append(self.piece_list[j])

                else:

                    self.piece_list.append(0)

            self.piece_matrix.append(self.piece_list)

            self.piece_list=[]#莫忘!

    def create_piece(self,x,y):

        #创建棋子

        piece=PieceModel(x,y)

        piece.id=self.create_piece_id(x)

        return piece

    def create_piece_id(self,x):

        #创建棋子的编号

        if x==0:

            Controller.__You_id+=1

            return Controller.__You_id

        else:

            Controller.__Me_id+=1

            return Controller.__Me_id

    def up(self,selected_piece):

        #向上移

        if selected_piece.x==0\

            or self.piece_matrix[selected_piece.x-1][selected_piece.y]!=0:

            return False

        else:

            self.piece_matrix[selected_piece.x-1][selected_piece.y]=selected_piece

            self.piece_matrix[selected_piece.x][selected_piece.y]=0

            selected_piece.x-=1

            return True

    def down(self,selected_piece):

        #向下移

        if selected_piece.x==len(self.piece_matrix)-1\

            or self.piece_matrix[selected_piece.x+1][selected_piece.y]!=0:

            return False

        else:

            self.piece_matrix[selected_piece.x+1][selected_piece.y]=selected_piece

            self.piece_matrix[selected_piece.x][selected_piece.y]=0

            selected_piece.x+=1

            return True

    def left(self,selected_piece):

        #向左移,或者矩阵转置+向上移

        self.transposition()

        result=self.up(selected_piece)

        self.transposition()

        if result:

            return True

        return False

    def right(self,selected_piece):

        #向右移

        self.transposition()

        result=self.down(selected_piece)

        self.transposition()

        if result:

            return True

        return False

    def action(self,piece,direction):

        #上1左2右3下4

        if direction==1:

            if self.up(piece):

                return True

        elif direction==2:

            if self.left(piece):

                return True

        elif direction==3:

            if self.right(piece):

                return True

        elif direction==4:

            if self.down(piece):

                return True

        return False

    def transposition(self):

        #矩阵转置及x,y互换

        for i in range(len(self.piece_matrix)):

            for j in range(i+1,len(self.piece_matrix)):

                self.piece_matrix[i][j],self.piece_matrix[j][i]\

                    =self.piece_matrix[j][i],self.piece_matrix[i][j]

            self.me_piece_data[i].x,self.me_piece_data[i].y\

            =self.me_piece_data[i].y,self.me_piece_data[i].x#这里原只有me_piece_data,怪不得黑棋坐标不对!

            self.you_piece_data[i].x,self.you_piece_data[i].y\

            =self.you_piece_data[i].y,self.you_piece_data[i].x

    def get_me_group(self,piece_list):

        #传入棋盘的一个行列表,从中获取并返回白棋组列表

        me_group=[]

        me_groups=[]

        for i in piece_list:

            if i in self.me_piece_data:

                me_group.append(i)

            else:

                if me_group:

                    me_groups.append(me_group)

                me_group=[]

        if me_group:#遍历完直接跳出,这里应有一处判断添加

            me_groups.append(me_group)

        return me_groups

    def get_me_group_head_adjacency_piece(self,me_piece_group):

        #传入白棋组,判断同行头的情况,返回黑棋组

        head=me_piece_group[-1]

        head_y=head.y

        you_group=[]

        while True:

            if head_y<len(self.piece_matrix)-1:

                if self.piece_matrix[head.x][head_y+1] in self.you_piece_data:

                    you_group.append(self.piece_matrix[head.x][head_y+1])

                    head_y+=1

                else:

                    return you_group

            else:

                return you_group

    def get_me_group_bottom_adjacency_piece(self,me_piece_group):

        #传入白棋组,判断同行尾的情况,返回黑棋组

        bottom=me_piece_group[0]

        bottom_y=bottom.y

        you_group=[]

        while True:

            if bottom_y>0:

                if self.piece_matrix[bottom.x][bottom_y-1] in self.you_piece_data:

                    you_group.append(self.piece_matrix[bottom.x][bottom_y-1])

                    bottom_y-=1

                else:

                    return you_group

            else:

                return you_group

    def judge_two_group(self,me_group,you_group):

        #判断两组胜负

        if len(me_group)>len(you_group):    

            return 1#白胜

        if len(you_group)>len(me_group):

            return 2#黑胜

        return 0

    def judge_win_or_not_on_line(self):

        #行遍历棋盘,判断胜负

        for item in self.piece_matrix:

            me_group_list=self.get_me_group(item)

            if me_group_list:

                for j in me_group_list:

                    you_head_group=self.get_me_group_head_adjacency_piece(j)

                    if you_head_group:

                        return self.judge_two_group(j,you_head_group)

                    you_bottom_group=self.get_me_group_bottom_adjacency_piece(j)

                    if you_bottom_group:

                        return self.judge_two_group(j,you_bottom_group)

        return 0

    def judge_win_or_not(self):

        #全遍历棋盘,判断胜负

        win_or_not_on_line=self.judge_win_or_not_on_line()

        if win_or_not_on_line:

            return win_or_not_on_line

        self.transposition()

        win_or_not=self.judge_win_or_not_on_line()

        if win_or_not:

            return win_or_not

        self.transposition()

        return 0

class View:

    '''显示棋盘,提示信息'''

    def __init__(self) -> None:

        self.manager=Controller()

    def main(self):

        flag=False

        round=0

        self.start()

        while True:

            round+=1

            self.round_sign(round)

            while True:

                me_choice=self.me_and_you()

                if me_choice==-1:

                    flag=True

                    break

                elif me_choice:

                    print('-----------------------------')

                    self.deplay_board()

                    break

                else:

                    continue

            if flag:

                break

            win_or_no=self.win_or_not_of_view()

            if win_or_no:

                if win_or_no==1:

                    print('\n','白胜,该棋结束')

                else:

                    print('\n','黑胜,该棋结束')

                break

            self.round_sign(round)

            while True:

                you_choice=self.you_and_me()

                if you_choice==-1:

                    flag=True

                    break

                elif you_choice:

                    print('-----------------------------')

                    self.deplay_board()

                    break

                else:

                    continue

            if flag:

                break

            win_or_no=self.win_or_not_of_view()

            if win_or_no:

                if win_or_no==1:

                    print('\n','白胜,该棋结束')

                else:

                    print('\n','黑胜,该棋结束')

                break

    def start(self):

        #开始棋局

        scale=int(input('输入棋子数:'))

        self.manager.create_board(scale)

        self.deplay_board()

    def end(self):

        end_or_not=input('是否结束该棋? (是y/Y)\n')

        if end_or_not=='y'or end_or_not=='Y':

            return -1

        return False

    def win_or_not_of_view(self):

        win_or_not=self.manager.judge_win_or_not()

        if win_or_not:

            return win_or_not

        return 0

    def deplay_board(self):

        #显示棋盘及操作说明

        for i in self.manager.piece_matrix:

            for j in i:

                if j and j.id<100:

                    print('白%d\t'%(j.id),end=' ')

                elif j and j.id>100:

                    print('黑%d\t'%(j.id%100),end=' ')

                else:

                    print(0,'\t',end=' ')

            print('\n')

        self.operation_illustrate()

    def operation_illustrate(self):

        for i in range(2):

            print()

        print('上1'.center(7,' '))

        print('左2  右3')

        print('下4'.center(7,' '))        

    def round_sign(self,round):

        #显示第几回合

        print('\n\n','第%d回合'.center(12,' ')%round,'\n')

    def is_number(self,number_or_not):

        try:

            int(number_or_not)

            return True

        except:

            return False

    def me_and_you(self):

        #白行动

        selected_piece_id=input('请白选择棋子:')

        selected_piece_direction=input('请选择方向:')

        if self.is_number(selected_piece_id)and self.is_number(selected_piece_direction):

            for i in self.manager.me_piece_data:

                if i.id==int(selected_piece_id):

                    if self.manager.action(i,int(selected_piece_direction)):

                        return True

        elif selected_piece_id==''or selected_piece_direction=='':

            return self.end()

        return False

    def you_and_me(self):

        #黑行动

        selected_piece_id=input('请黑选择棋子:')

        selected_piece_direction=input('请选择方向:')

        if self.is_number(selected_piece_id) and self.is_number(selected_piece_direction):

            for i in self.manager.you_piece_data:

                if i.id%100==int(selected_piece_id):

                    if self.manager.action(i,int(selected_piece_direction)):

                        return True

        elif selected_piece_id==''or selected_piece_direction=='':

            return self.end()

        return False

class MainController:

    def __init__(self) -> None:

        self.game=View()

    def check_rule(self):

        print()

        print('''游戏名:以多胜少

游戏规则:如果在一条直线上(无论横或竖),

    同属一方的相邻的棋子形成一个棋组(两个及两个以上);

    如果我方的棋组与对方的一个棋子相邻,

    或者如果与对方的棋组相邻,且棋子数更多(棋子数相等则不分胜负),

    则我方胜;

    反之对方胜。

游戏的开发思想:

    此代码采用MVC的模式。

    MVC模式是软件工程中常见的一种软件架构模式,该模式把软件系统(项目)分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。

使用MVC模式有很多优势,例如:简化后期对项目的修改、扩展等维护操作;使项目的某一部分变得可以重复利用;使项目的结构更加直观。

具体来讲,MVC模式可以将项目划分为模型(M)、视图(V)和控制器(C)三个部分,并赋予各个部分不同的功能,方便开发人员进行分组。

(1)视图(View):负责界面的显示,以及与用户的交互功能,例如表单、网页等。

(2)控制器(Controller):可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型。

实际开发中,通常用控制器对客户端的请求数据进行封装(如将form表单发来的若干个表单字段值,封装到一个实体对象中),然后调用某一个模型来处理此请求,最后再转发请求(或重定向)到视图(或另一个控制器)。

(3)模型(Model):模型持有所有的数据、状态和程序逻辑。模型接受视图数据的请求,并返回最终的处理结果。)

        print()

    def begin(self):

        self.game.main()

class MainView:

    def __init__(self) -> None:

        self.mainmanager=MainController()

    def menu(self):

        print('__________________________')

        print()

        print('以多胜少')

        print('1.查看游戏规则')

        print('2.开始下棋')

        print('3.退出')

        print('__________________________')

    def main(self):

        while True:

            self.menu()

            self.mainmanager.game.manager=Controller()

            choice=input('请选择:')

            if choice=='1':

                self.mainmanager.check_rule()

            elif choice=='2':

                self.mainmanager.begin()

            elif choice=='3':

                break

m=MainView()

m.main()

  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值