基于F#实现3x3彩色2048纸牌游戏:filter函数实现问询
实现3x3颜色版2048的filter函数(F#)
需求背景
需要开发一款3x3棋盘、以颜色替代数字的2048纸牌游戏,核心是实现filter函数——筛选出棋盘state中第k列的所有棋子。相关类型定义、函数签名及示例如下:
type pos = int*int // 棋盘坐标(非像素)的二维向量 type value = Red | Green | Blue | Yellow | Black // 棋子颜色值 type piece = value*pos // 棋子(颜色+位置) type state = piece list // 棋盘状态是棋子的列表 val filter: k: int -> s: state -> state // 示例: // > filter 0 [(Blue, (1, 0)); (Red, (0, 0))];; // val it: state = [(Blue, (1, 0)); (Red, (0, 0))] // > filter 1 [(Blue, (1, 0)); (Red, (0, 0))];; // val it: state = []
当前思路与问题
计划针对3x3棋盘的列号(k取值为0、1、2)使用模式匹配,写出了如下框架,但不清楚具体实现:
let filter (k: int) (s: state) : state = match k with | 0 -> | 1 -> | 2 ->
解决方案
其实不需要对k做模式匹配,因为不管k是0/1/2,筛选逻辑完全一致:保留所有棋子位置中列号等于k的元素。用F#的List.filter函数可以简洁实现,这也是更符合函数式编程风格的写法。
完整实现代码
type pos = int*int type value = Red | Green | Blue | Yellow | Black type piece = value*pos type state = piece list let filter (k: int) (s: state) : state = s |> List.filter (fun (_, (_, col)) -> col = k)
代码解释
List.filter接收一个判断函数和列表,返回符合判断条件的元素列表- 匿名函数
fun (_, (_, col)) -> col = k:解构每个棋子piece,忽略颜色值,再解构位置pos忽略行号,取出列号col,判断是否等于目标列k
测试验证
运行示例中的测试用例:
// 测试用例1 filter 0 [(Blue, (1, 0)); (Red, (0, 0))] // 输出:[(Blue, (1, 0)); (Red, (0, 0))] // 测试用例2 filter 1 [(Blue, (1, 0)); (Red, (0, 0))] // 输出:[]
若坚持使用模式匹配的写法
如果一定要保留对k的模式匹配框架,其实每个分支的逻辑都是一样的,直接复用过滤逻辑即可:
let filter (k: int) (s: state) : state = let filterCol col = s |> List.filter (fun (_, (_, c)) -> c = col) match k with | 0 -> filterCol 0 | 1 -> filterCol 1 | 2 -> filterCol 2 | _ -> [] // 处理超出3x3范围的k,返回空列表
内容的提问来源于stack exchange,提问作者Hoodwinked
相关产品推荐
相关产品推荐

