通过as写一个简单的按键_自己写一个简单的二维魔方游戏

周日下午一口气刷了4集《最强大脑》,很久不看综艺,发现这个节目还挺有意思的,清北这些大佬确实有过人之处。在看视频过程中印象最深的一幕莫过于北大王心冉对阵清华张洗月,她们比的题目是盲拧一个二维的魔方,要求记住一个5x5的棋盘,然后凭闭眼凭感觉复原。这道题很难,一般人睁着眼都很难完成,闭着眼难度可想而知。

我自问是没有这能力闭眼复原棋盘的,但是我也想玩这个游戏,为此今天晚上花了几个小时给自己写了个简单版的游戏,边玩看能不能训练出她们这样的能力。

游戏界面很简陋,大致长下面这样吧

8f1d248aed5f21589e5173f4e92dd0c3.png

5x5的棋盘,每一行都是一个颜色,游戏开始时会随机打乱局面,选手要根据对每一行或每一列进行移动,如果能把棋盘复原就胜利了

简单打乱之后局面变成这样了

9f2d5d31cab40c64735bd12bd446c528.png

好晕,我不会玩了,完全没思路应该怎么走,认输吧,明棋我也不会。

接下来讲讲代码,代码很简单,总共200多行吧,以下是关键部分

fn main() -> Result>> {    // Terminal initialization    let stdout = io::stdout().into_raw_mode()?;    let stdout = MouseTerminal::from(stdout);    let stdout = AlternateScreen::from(stdout);    let backend = TermionBackend::new(stdout);    let mut terminal = Terminal::new(backend)?;    terminal.hide_cursor()?;    // Setup event handlers    let events = Events::new();    let mofang_size = 5_usize;    let colors: Vec = vec![        Color::Red,        Color::Yellow,        Color::Blue,        Color::Green,        Color::Cyan,    ];    let mut color_matrix: Vec>> = vec![];    for i in 0..mofang_size {        color_matrix.push(vec![colors[i]; mofang_size]);    }    let mut constraints = vec![];    for _i in 0..mofang_size {        constraints.push(Constraint::Ratio(1, mofang_size as u32));    }    let mut cur_row = 0;    let mut cur_col = 0;    let start_time = Instant::now();    loop {        terminal.draw(|mut f| {            let size = f.size();            let block = Block::default()                .borders(Borders::ALL)                .title("2D Mofang game")                .border_type(BorderType::Rounded);            f.render_widget(block, size);            let chunks = Layout::default()                .direction(Direction::Vertical)                .constraints(                    [                        Constraint::Percentage(10),                        Constraint::Percentage(80),                        Constraint::Percentage(10),                    ]                    .as_ref(),                )                .split(f.size());            // render header            {                let chunks = Layout::default()                    .direction(Direction::Horizontal)                    .constraints(                        [                            Constraint::Percentage(10),                            Constraint::Percentage(80),                            Constraint::Percentage(10),                        ]                        .as_ref(),                    )                    .split(chunks[0]);                                let cur_time = Instant::now();                let time_passed = cur_time.duration_since(start_time).as_secs();                let time_str = format!("{} seconds passed!", time_passed);                let s1 = &time_str;                let t1 = [Text::raw(s1)];                                let title = Paragraph::new(t1.iter())                    .block(Block::default())                    .alignment(Alignment::Center);                f.render_widget(title, chunks[1]);                }            {                let chunks = Layout::default()                    .direction(Direction::Horizontal)                    .constraints(                        [                            Constraint::Percentage(10),                            Constraint::Percentage(80),                            Constraint::Percentage(10),                        ]                        .as_ref(),                    )                    .split(chunks[1]);                {                    let row_chunks = Layout::default()                        .direction(Direction::Vertical)                        .constraints(constraints.as_ref())                        .split(chunks[1]);                    for (i, row_chunk) in row_chunks.into_iter().enumerate() {                        let col_chunks = Layout::default()                            .direction(Direction::Horizontal)                            .constraints(constraints.as_ref())                            .split(row_chunk);                        for (j, col_chunk) in col_chunks.into_iter().enumerate() {                            let mut block = Block::default()                                .borders(Borders::ALL)                                .style(Style::default().bg(color_matrix[i][j]));                            if cur_row == i && cur_col == j {                                block = block.title("|--");                            } else if cur_row == i {                                block = block.title("--");                            } else if cur_col == j {                                block = block.title("|");                            }                            f.render_widget(block, col_chunk);                        }                    }                }            }        })?;        if let Event::Input(key) = events.next()? {            if key == Key::Char('q') {                break;            } else if key == Key::Down {                if cur_row < mofang_size - 1 {                    cur_row += 1;                }            } else if key == Key::Up {                if cur_row > 0 {                    cur_row -= 1;                }            } else if key == Key::Right {                if cur_col < mofang_size - 1 {                    cur_col += 1;                }            } else if key == Key::Left {                if cur_col > 0 {                    cur_col -= 1;                }            } else if key == Key::Char('a') {                row_cycle(&mut color_matrix, cur_row);            } else if key == Key::Char('s') {                col_cycle(&mut color_matrix, cur_col);            }        }    }    Ok(())}fn row_cycle(color_matrix: &mut Vec>>,     // 按行轮换一次颜色(左右轮换)    let mut row = color_matrix[row_idx].clone();    let l = row.len();    let first = row[0];    for i in 0..l - 1 {        row[i] = row[i + 1];    }    row[l - 1] = first;    color_matrix[row_idx] = row;}fn col_cycle(color_matrix: &mut Vec>>,     // 按列轮换一次颜色(上下轮换)    let l = color_matrix[0].len();    let first = color_matrix[0][col_idx];    for i in 0..l - 1 {        color_matrix[i][col_idx] = color_matrix[i + 1][col_idx];    }    color_matrix[l - 1][col_idx] = first;}

梳理一下思路:

  1. 初始化界面布局,也就是安排哪些地方放标题,哪些地方摆放棋盘

  2. 在该摆放棋盘的位置初始化一个5x5的棋盘

  3. 加上事件监听程序,也就是监听按键,当按下上下左右方向键的时候要移动目标行或列,当按下A或者S键的时候对行/列做一次轮换

  4. 编写轮换算法,这个其实是最简单的了,就是变换一个颜色矩阵

玩游戏很难做游戏是不是很简单?不过这种棋盘复原的问题用计算机解应该也可以,我搜索了一下相关算法,发现要用到MCTS算法,但是没找到现成的例子,感兴趣的小伙伴可以留言我们交流一下

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值