1、使用GM8制作五子棋使用GM8制作五子棋最主要的对象就是:对象信息: obj_init精灵: 固体: false可见: true深度: 0持久: false父对象: 遮罩: 创建事件:执行代码:my_turn=1 /我的顺序为1,黑子先手offset_x=0 /可以放置棋子的位置offset_y=0min_row=15 /目前棋盘上棋子区域最小的行min_col=15 /目前棋盘上棋子区域最小的列max_row=1 /目前棋盘上棋子区域最大的行max_col=1 /目前棋盘上棋子区域最大的列计时器事件-计时器0:用于判断放置黑子之后,是否黑子获胜,并通过scr_go(),自动放置白子执行代码:
2、if(instance_number(obj_black)4) /如果黑子数量大于4 if(scr_iswin(offset_x div 32,offset_y div 32,obj_black) /判断放下的黑子是否能赢 instance_create(room_width/2,room_height/2,obj_showinfo)/如果黑子赢,创建显示对象 obj_showinfo.image_index=0 if(!instance_exists(obj_showinfo) /如果黑子没有赢 scr_go() /启动scr_go(),自动放置白子 alarm1=1 /启动时钟1事件计时器
3、事件-计时器1: :用于判断放置白子之后,是否白子获胜,并将我的顺序设置为1,可以放置黑子执行代码:if(instance_number(obj_white)4) /如果白子数量大于4 if(scr_iswin(offset_x div 32,offset_y div 32,obj_white) /判断指定位置白子是否能赢 instance_create(room_width/2,room_height/2,obj_showinfo)/如果白子赢创建显示对象 obj_showinfo.image_index=1 my_turn=1 /将我的顺序重置为1,以便放置黑子步事件:获取鼠标指针所对应的
4、棋盘中的位置执行代码:offset_x=(round(mouse_x / 32)*32 /鼠标指针位置除以32四舍五入之后再乘32offset_y=(round(mouse_y / 32)*32鼠标事件-全局左键按下:用于放置黑子执行代码:if(offset_x=32 and offset_y=32 and offset_x=480 and offset_y=32 and offset_y=32 and offset_x=480 and offset_y=480 and !position_empty(offset_x,offset_y) /如果鼠标在棋盘区域,并且指定位置存在棋子 show_
5、message(scr_checked(instance_position(offset_x,offset_y,all) /判断该位置的价值绘制事件:用于绘制棋盘,画指针执行代码:draw_set_alpha(0.5) /设置透明度for(i=1;i=32 and offset_y=32 and offset_x=480 and offset_y=480) /如果鼠标指针在棋盘内 if(my_turn=1) draw_circle(offset_x,offset_y,5,0) /跟随鼠标指针的黑点 else /跟随鼠标指针的白点 draw_set_color(c_white) draw_cir
6、cle(offset_x,offset_y,5,0) draw_set_color(c_black) draw_text(500,180,black:+string(instance_number(obj_black) /绘制文本黑子数量draw_text(500,220,white:+string(instance_number(obj_white) /绘制文本白子数量键盘按下事件-R-key 键:游戏重置执行代码:room_restart()除了obj_init之外,还有obj_black与obj_white用于显示黑子与白子,什么也不用做。另外还有obj_showinfo,用于在游戏结束
7、时显示是玩家胜利还是电脑胜利。游戏的执行顺序是,游戏启动,当玩家按下鼠标左键,创建黑子,第一个被调用的函数是:scr_rowcol(),该函数用于设置当前棋盘上的棋子区域的四个值,即最小行最大行最小列最大列。之后,在对象的时时钟0事件中调用了scr_iswin()函数用于判断黑棋是否获胜,再调用scr_go()用于放置白棋。之后启动时钟1事件,判断白棋是否获胜重置my_turn变量。一直重复,直到一方获胜。scr_iswin()仅判断指定位置的指定棋子是否会获胜,其中也并未引用其他函数。scr_go()用于电脑放置白色棋子,其中也调用了函数:scr_rowcol(),用于重置棋盘棋子区域的值。
8、同时还调用了函数:scr_checked(),该函数用于获取在某一位置放置某一棋子时的得分情况。而在函数scr_checked()中,调用了函数scr_move()用于判断能否向某一个方向移动,同时还调用了函数:scr_gets_oneline()用于获取一行的得分情况。这样整个过程就明晰了。几个脚本之间的关系如下:以上脚本中,scr_iswin()相对独立,不被其他脚本调用,用于判断是否存在黑白双方有五个子连在一起的情况。scr_go()用于电脑AI下棋,在整个体系中处于核心位置,其调用scr_checked()用于获取得分情况,调用scr_rowcol()仅用于重置棋盘下子区域大小,便于判
9、断。scr_checked()则属于二级核心的位置,该脚本为scr_go()服务,同时也需要scr_move()与scr_gets_oneline()为自己服务。scr_move()与scr_gets_oneline()处于最底层,这两个脚本为scr_checked()提供服务,分别用于判断能否向某个方向移动,和获取一行的得分情况。介绍完了整个脚本体系。下面就按顺序来依次说明几个脚本的具体内容。scr_iswin(),判断游戏是否结束,即有没有黑子或者白子连成一排5个棋子的情况。var t_x,t_y,start_x,end_x,start_y,end_y,num,i,flag,obj_tar
10、get; /定义一组变量t_x=argument0 /落下子的位置横坐标t_y=argument1 /落下子的位置纵坐标obj_target=argument2 /落下的子num=0 /初始数量为0start_x=t_x-4 /当前位置向左的第4个位置start_y=t_y-4 /当前位置向上的第4个位置end_x=t_x+4 /当前位置向右的第4个位置end_y=t_y+4 /当前位置向下的第4个位置for(i=start_x;i=end_x;i+=1) /从左向右循环 if(position_meeting(i*32,t_y*32,obj_target) /如果遇到同样的棋子 num+=1
11、 /数量加1 if(num=5) return true /如果数量等于5,返回true else num=0; /如果没遇到则数量置为0for(i=start_y;i=end_y;i+=1) /从上到下循环 if(position_meeting(t_x*32,i*32,obj_target) num+=1 if(num=5) return true else num=0;flag=min(end_x-start_x,end_y-start_y) /找出横纵坐标中的最小值for(i=0;i=flag;i+=1) /开始循环 if(position_meeting(start_x+i)*32,
12、(start_y+i)*32,obj_target) /从左上向右下 num+=1; if(num=5) return true else num=0;for(i=0;i=flag;i+=1) /开始循环 if(position_meeting(start_x+i)*32,(end_y-i)*32,obj_target) /从从左下到右上 num+=1; if(num=5) return true else num=0;return false /如果都没有等于5,返回falsescr_go,白子(电脑AI所执棋子)自动下棋。var i,j,temp_obj,ai_score,player_s
13、core,index,my_col,my_row,max_score,temp,temp_list,my_list;index=0; /索引为0my_list=ds_list_create() /创建一个列表用于存放变量for(i=min_row;i=max_row;i+=1) /从行开始循环 for(j=min_col;j=max_col;j+=1) /在列中循环 if(position_empty(j*32,i*32) /如果当前位置为空 temp_obj=instance_create(j*32,i*32,obj_white) /先创建一个白棋子 temp_obj.visible=0 /
14、白棋子不可见 ai_score=scr_checked(temp_obj) /检测当前放子之后的AI得分 with(temp_obj) /销毁创建的白棋子 instance_destroy() temp_obj=instance_create(j*32,i*32,obj_black) /再创建一个黑棋子 temp_obj.visible=0 /黑棋子不可见 player_score=scr_checked(temp_obj) /检测放黑子之后玩家得分 with(temp_obj) /销毁黑棋子 instance_destroy() ds_list_add(my_list,ai_score+pl
15、ayer_score) /将AI得分与玩家得分之和添加到列表 my_colindex=j /将列位置存到数组 my_rowindex=i /将行位置存以数组 index+=1 /索引增加1 max_score=0 /将最高分置为0for(i=0;imax_score) max_score=temp /获取最高得分temp_list=ds_list_create() /再创建一个临时列表for(i=0;iindex;i+=1) /遍历 temp=ds_list_find_value(my_list,i) /找出指定位置的值 if(temp=max_score) ds_list_add(temp_
16、list,i) /将所有最大分值位置添加到临时列表temp=ds_list_size(temp_list) /获取列表长度temp=irandom_range(0,temp-1) /随机取一个位置index=ds_list_find_value(temp_list,temp) /找出该随机位置的值instance_create(my_colindex*32,my_rowindex*32,obj_white) /在该随机位置创建白棋子obj_init.offset_x=my_colindex*32 /重置offset_xobj_init.offset_y=my_rowindex*32 /重置of
17、fset_yscr_rowcol(my_colindex*32,my_rowindex*32) /调用scr_rowcol定义可下子区域scr_rowcol()重新定义可下子区域(最大最小行列)if(argument1 div 32 -2)min_row) min_row=argument1 div 32 -2 /获取最小行if(min_row1) min_row=1 /最小行超出边界if(argument0 div 32 -2)min_col) min_col=argument0 div 32 -2 /获取最小列if(min_colmax_row) max_row=argument1 div
18、 32 +2 /获取最大行if(max_row15) max_row=15 /最大行超出边界if(argument0 div 32 +2)max_col) max_col=argument0 div 32 +2 /获取最大列if(max_col15) max_col=15 /最大列超出边界scr_checked(),检测得分情况var t_x,t_y,obj_target,i,j,num,state1,state2,temp,temp_s;t_x=argument0.x /获取放置棋子横坐标t_y=argument0.y /获取放置棋子纵坐标obj_target=argument0.objec
19、t_index /获取实例的对象索引num=0 /数量等于0i=0j=0/水平向左检测while(true) i-=1; temp=scr_move(t_x,t_y,i,0,obj_target) /调用move函数,当前位置向左移动纵坐标不变横坐标每次减1 if(temp=1) num+=1 /如果返回结果为1(移动位置与目标对象相同)则增加1 else break; /如果没有返回1则跳出循环if(temp=0) /如果temp=0(移动到位置为空) if(t_x div 32+i0) state1=l /如果未碰到边界返回状态1为l else state1=d /如果碰到边界返回状态1为
20、delse state1=d /如果不为0则状态1为d/水平向右检测i=0while(true) i+=1; temp=scr_move(t_x,t_y,i,0,obj_target) if(temp=1) num+=1 else break; if(temp=0) if(t_x div 32+i0) state1=l else state1=delse state1=d/垂直向下检测i=0while(true) i+=1; temp=scr_move(t_x,t_y,0,i,obj_target) if(temp=1) num+=1 else break; if(temp=0) if(t_y
21、 div 32+i0 and t_x div 32+i0) state1=l else state1=delse state1=d/斜向右下角检测i=0while(true) i+=1; temp=scr_move(t_x,t_y,i,i,obj_target) if(temp=1) num+=1 else break; if(temp=0) if(t_y div 32+i16 and t_x div 32+i0 and t_y div 32+i15) state1=l else state1=delse state1=d/斜向右上角检测i=0j=0while(true) i+=1; j-=1
22、; temp=scr_move(t_x,t_y,i,j,obj_target) if(temp=1) num+=1 else break; if(temp=0) if(t_x div 32+i0) state2=l else state2=delse state2=d/返回结果num+=1temp_s3=scr_gets_oneline(state1+string(num)+state2) /获取左下右上得分return (temp_s0+temp_s1+temp_s2+temp_s3) /返回4个方向最终结果得分scr_gets_oneline()获取一行得分情况var num;num=real(string_char_at(argument0,2) /获取中间的值(多少个)if(num4) return 100000 /如果有5子相连返回100000else if(num=1) return 0 /如果仅有1个返回0else if(string_count(d,argument0)=2) return 0 /如果字串中有两个d两头被堵 else if(string_count(d,argument0)=1) /如果一头被堵
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1