/** * @author jiutou * @updateTime 2022/12/02 * @tip 6-3 平均分与大小配对 * @description * 5,0,0,0,0 4,1,0,0,0 3,2,0,0,0 3,1,1,0,0 2,2,1,0,0 2,1,1,1,0 1,1,1,1,1 6-3 平均分与大小配对 一.挑战模式 1.参数默认值:①堆数:4。②每堆数 量:3,4,4,9 2.参数范围:①总数:2~30 ②堆数: 1~(n-1)【n 表示总数】 3.过程记录:无 二.练习模式 一级:L1或 W2 二级:L2或 W3 三级:L3或 W4 四级:L4或 w5 五级:L5或 W6 必胜策略:判断当前状态是否属于 胜点集,如果是则随机操作, 负点集,选择一种操作方式,使得操作后的状态属于胜点集。 以下是将游戏的所有状态按胜负点分类的过程。 ①生成游戏状态集 S,由于游戏参数范围是 2~30,即可以将游戏状态集看成有29个游戏状态子集组合而成, 下面描述游戏状态集生成的过程。为描述方面,每一个游戏状态都用一个一维 30 元向量表示, (1)棋子颗数为2时,状态集元素就 2 个(a2=2)ps:a1=1,a0=0 即(2,0,....,0)、(1,1,....,0); (2)棋子颗数为3时,状态集元素为 3 个(a3=2+1+a0=3)【a0 即没有棋子时状态数为 0,虽然游戏过程中不会有这样状态,但不影响其取值】,分别是(3,0,....,0)、(2,1,....,0)、(1,1,1,....,0); (3)棋子颗数为4时,状态集元素为 5 个(a4=2+2+a1=5)【a1即只有 1 颗棋子时状态数为 1,虽然游戏过程中不会有这样状态,但不影响其取值】,分别是(4,0,....,0)、(3,1,....,0)、(2,2,....,0)、(2,1,1....,0)、(1,1,1,1....,0); (4)棋子颗数为5时,状态集元素为 7 个(a5=2+2+a2+a1=7),分别是(5,0,....,0)、(4,1,....,0)、(3,2,....,0)、(3,1,1....,0)、(2,2,1....,0)、(2,1,1,1....,0)、(1,1,1,1,1....,0); (5)棋子颗数为6时,状态集元素为11 个(a6=2+3+a3+a2+a1=11),分别是(6,0,....,0)、(5,1,....,0)、(4,2,....,0)、(3,3,0....,0)、(4,1,1....,0)、(3,2,1....,0)、(2,2,2....,0)、(3,1,1,1,0....,0)、(2,2,1,1....,0)、(2,1,1,1,1....,0)、(1,1,1,1,1,1....,0), //7.0.0.0.0.0.0|6.1.0.0.0.0.0|5.2.0.0.0.0.0|5.1.1.0.0.0.0|4.3.0.0.0.0.0|4.2.1.0.0.0.0|4.1.1.1.0.0.0|3.3.1.0.0.0.0|3.2.2.0.0.0.0|3.2.1.1.0.0.0|3.1.1.1.1.0.0|2.1.1.1.1.1.0|2.2.1.1.1.0.0|2.2.2.1.0.0.0|1.1.1.1.1.1.1 观察上面的模式易得递归式:an=2+[n/2]+an-3+an-2+.....a2+a1(n≥3)【其中[n/2]表示向下取整,表示的意义是当棋子数量为 n 时,分成两部分的方式数量比如 n 等于 7 时,[n/2]=3,具体为(6,1)、(5,2)、(4,3)】; an表示当棋子颗数为 n 时,游戏状态的个数,具体得到每一个状态,即得到棋子数量为 n 时的状态集的方式为:考虑递归式中每一部分的含义, 第一个2表示(n,0,0,0.....,0)和(1,1,1,....1)【共n 个1】; 第二个[n/2]表示由(n-1,1,0,0,....0)开始,坐标分量 1 逐次减 1,坐标分量 2 逐次加1,直到坐标分量1 和坐标分量 2 的差不大于 1 为止。; 第三部分 an-3,表示在前 n-3 个分量都为1 的基础上,逐次与 an-3中的状态做向量加法,比如 a6中的 a3所对应的 3 个状态集可以这么得到:(1,1,1,0,0,0)+(3,0,....,0);(1,1,1,0,0,0)+(2,1,....,0)、(1,1,1,0,0,0)+(1,1,1,....,0)。往下 an-4,an-5.....依次类推,即可得到整个an的元素。 每一种棋子数量对应着一个参数,这样游戏状态集就可以表示为S={{S2};{S3};{S4};....{S30}}【下标表示棋子的数量,{Sn},表示棋子数量为n 时,对应的游戏状态集】 ②每一种棋子数量的游戏状态集按胜败分类的方式都是一致的,下面以n=30 为例,进行说明:全为 1 的矩阵是游戏的终点状态,也是游戏的最终胜点,因为抢占该状态者胜,面临该状态者负,将这个状态存入 W1; ③显然,只要存在一种进入 W1的方式的状态都是败点,而且不难推出满足这样要求的状态满足条件:有且只有 1 个分量大于 1,比如(30,0,0,0,......0)、(26,1,1,1,1,0,0,.....0)等等,满足这样条件的点都是败点,我们将它们存入L1; ④更新差集ΔS=S-L1-W1后,继续对ΔS 中的每一个元素进行规则遍历,如果某个状态ai(i有可能不唯一)实行任意一合法操作之后,所得到的状态都属于 L1,则该状态也属于必胜集,将其存入 W2; ⑤更新差集ΔS=ΔS-W2后,对ΔS 中的每一个元素进行规则遍历,即对ΔS 中每一个游戏状态逐一实行所有可能的操作,若某个状态 ai(i 可能不唯一)在实行规则遍历的过程中,存在某一种操作使得实行该操作后所得到的新状态 ai’属于 W2,则这个状态ai属于败点集,将这个状态存入 L2; ⑥重复④和⑤,直至ΔS 为空。】 * */ import { GameAutoWay } from '../common/pojo'; import exampleData10_2 from './data'; export declare class GameData6_3 { typeSet?: number | undefined; desk: number[]; player: number; constructor(player: number, desk?: number[]); } export declare class GameAction6_3 { action: number[][]; actionAfter: number[][]; constructor(action: number[][], actionAfter: number[][]); } export declare class GameConfig6_3 { n: number; desk: number[]; constructor(n: number, desk: number[]); } export default class example6_3 { sMap: Map; persistenceData: exampleData10_2; getRiddleByLev(level: number, config: any): GameData6_3; getRiddle(config: GameConfig6_3): GameData6_3; checkRiddle(deskData: GameData6_3): number; checkDesk(deskData: GameData6_3): number; doAction(deskData: GameData6_3, dataAction: GameAction6_3): [flagResult: number, dataResult: GameData6_3]; checkAction(deskData: GameData6_3, dataAction: GameAction6_3): number; getActionAuto(deskData: GameData6_3): GameAutoWay; getDw(chess: number): Set; getDl(chess: number): Set; getActionAutoCommon(deskData: GameData6_3, dw: Set, dl: Set): GameAutoWay; getAllDesk(n: number): void; getAllAction(desk: number[]): GameAction6_3[]; getEmptyAction(desk: number[], action: number[][]): number[]; getSplitAction(n: number): Set; desksort(desk: number[]): number[]; fillZero(desk: number[], n: number): number[]; actionToStr(action: GameAction6_3): string; deskToStr(desk: number[]): string; writer(filename: string, lw: Map>): void; }