zoukankan      html  css  js  c++  java
  • coding game, 边打游戏边学编程,是一种怎么样的体验?

    前言

    hello,大家好,我是bigsai,好久不见,甚是想念!

    在日常生活中,很多人喜欢玩游戏,因为游戏中有着对抗博弈、控制的喜悦,用灵魂指法完成一波靓丽的操作。

    但实际上,你的按键都是对应代码中一个个方法函数去执行操作,并且界面做到一个图形变化渲染让你感觉你控制的是这个图形界面。

    虽然游戏的底层都是一行行代码堆砌的逻辑,但是我们对其并没有半点兴趣因为写代码的过程枯燥无趣,完全需要脑子去抽象出一个页面、执行逻辑,出错的时候有很简单的找了半天…… 输出、debug各种方式去找问题。

    对于咱们这种懒人来说,想要锻炼自己编程能力、算法真的是进入一种畏难的无限死循环,希望要么简单点、要么有趣点,写的东西最好也能像有些开发那样看得见,摸得着,学习别那么难。

    这不,今天就发现了一个非常适合初、中级学者锻炼自己编程的网站:codingame一个边玩游戏边学编程的网站

    网站主页为:https://www.codingame.com/start

    网站介绍

    我们在学习技术、学习算法的时候,都喜欢看一些图将抽象内容具体化,甚至是如果有一些动图如果能够模拟一下程序执行逻辑之类的那就更受欢迎了,但是往往这类内容涉及到的底层非常多,并且优质的内容非常稀疏,但我今天推荐的这个网站真的是挺让人惊喜的,网站进入的第一感觉就是:卧槽,这是小霸王嘛? 啥玩意啊。

    一些小游戏动画切换背景,看着codingame这个url你丝毫不会想到这个网站跟编程有啥任何关系,只会想到:

    • 这到底是个啥?
    • 谷歌翻译一下看看……

    注册个账号登录之后才能显示更多的内容,仔细看下背景右侧还是有一些代码的,还是有一些非常神秘的感觉。

    image-20211103000352257

    登录之后,左上角的practice可以进行一些练习,页面会有各种难度的游戏问题,这些问题都有一个小的游戏背景、规则、考察点等待你去完成,比如easy难度的大部分都是字符串、哈希、循环控制这类问题,而mid难度的考察点更广泛比如很多二分查找、bfs、图论等等,如果英文不好可以借助翻译中英对比着看(狗头举手),对于hard难度的有兴趣可以自行挑战。

    image-20211103233203028

    对于这里面的问题,有的是文本形式的,但是更多的是小游戏方式有动画更加直观。

    还有一个非常重要的是,它支持多种编程语言,不管你是那种主流语言的爱好者,都可以畅想边玩游戏边学编程的快乐。

    easy初体验:ASCII的艺术

    这里和大家一起体验一下easy题怎么玩,我首先点进去的是一个叫ASCII Art的题.

    地址为:https://www.codingame.com/ide/puzzle/ascii-art

    刚进来就是一种黑色科技感十足,读完题可能有些小伙伴很懵逼,这是啥玩意,这个程序又跟我们平常见得有点不一样,不需要像力扣那样完成整个方法,也不是和acm那种提交整个可执行代码提交,这个程序它会事先声明好一些内容你只需要在它提示的地方写对应逻辑的代码就可以了,并且所有的结果要打印出来。

    但是细心的小伙伴会发现这个其实就是和我们日常的刷题很像很像,不就换个样子嘛,没啥不一样的。

    image-20211103235700708

    而这题的题意也很简单,我口述一下(可能不标准):

    给机场你经常看到这个牛批的显示屏:(图片)

    你有没有问过自己,在一个好的旧终端上怎么显示这个数字?(我怎么会难为我自己呢),我们有:用ASCII艺术

    ASCII 艺术允许您使用字符来表示。 准确地说,在我们的例子中,这些形式是词。 例如,单词“MANHATTAN”可以在 ASCII 艺术中显示如下:

    image-20211104000420895

    这个就有点似曾相识了,我也曾打印过大的0-9……

    在看输入输出和其他要求

    输入

    第 1 行:宽度L以 ASCII 艺术表示的字母。所有字母的宽度相同。

    第 2 行:高度H以 ASCII 艺术表示的字母。所有字母的高度相同。

    第 3行:待输出的文本T,有n个ASCII字符组成。

    后面几行:字符串 ABCDEFGHIJKLMNOPQRSTUVWXYZ? 以 ASCII 艺术字(输出到屏幕结果)表示。

    输出

    文本 T在 ASCII 艺术中。
    字符 a 到 z 在 ASCII 艺术中显示为大写的等效字符。
    不在区间 [az] 或 [AZ] 中的字符将在 ASCII 艺术中显示为问号。

    问题分析:

    这虽然是个简单的问题,但是怎么分析呢?

    对于给定的宽度L,和高度H,其实就是限定了每个字符在控制台的大小,这个如何理解呢,举个例子你就能明白。对于0来说,不同宽高的0可能长得样子不一样滴:

    # # #   # # #   # # # #
    #   #   #   #   #     #
    # # #   #   #   #     #
            #   #   #     #
            # # #   # # # #
    
    3*3     3*5      4*5
    圆润型   瘦长型    标准型
    

    其实也就是限定宽高每个字符你可以迅速锁定它的位置,存储方面不用多想肯定是个二维的存储(多个一维或者二维)。

    在输出的时候,根据字符计算 对应的位置,对应输出就可以了,考虑到一些小白玩家还是可能不太明白,我贴上自己的代码,仅供参考:

    import java.util.*;
    import java.io.*;
    import java.math.*;
    
    /**
     * Auto-generated code below aims at helping you parse
     * the standard input according to the problem statement.
     **/
    class Solution {
    
        public static void main(String args[]) {
            Scanner in = new Scanner(System.in);
            int L = in.nextInt();//宽
            int H = in.nextInt();//高
            char ch[][]=new char[H][L];
            if (in.hasNextLine()) {
                in.nextLine();
            }
            String T = in.nextLine().toUpperCase();
            for (int i = 0; i < H; i++) {
                String ROW = in.nextLine();//输入每一行
                ch[i]=ROW.toCharArray();//赋值给对应行
            }
            char value[][]=new char[H][T.length()*L];
            for(int i=0;i<T.length();i++){
                char temp=T.charAt(i);
                int index=temp-'A';
                if(index<0||index>26)
                    index=26;//不是字母统统问号 ???
                
                for(int j=0;j<H;j++){
                    
                    for(int q=0;q<L;q++)
                    {
                        value[j][q+i*L]=ch[j][q+L*index];//赋值给待输出结果
                    }
                }
            }
            for(char tem[]:value){
                for(char temp:tem){
                    System.out.print(temp);
                }
                System.out.println();
            }
    
            // Write an answer using System.out.println()
            // To debug: System.err.println("Debug messages...");
    
            //System.out.println("answer");
        }
    }
    

    20211104125804

    测试完提交即可。

    mid初体验二分

    看完一个easy题,你可能觉得好像也没啥哈,那行,咱们一起看个经典的mid题:

    链接为:https://www.codingame.com/ide/puzzle/shadows-of-the-knight-episode-1

    image-20211104141808736

    这个题具体要求大家可以自行到上面看看,但是大概的意思就是:

    告诉你你在的区域长宽告诉你你的初始点

    你的目标是最终走到某个终点,不告诉你具体坐标,只告诉你目标点在你当前点的方位(有八个方向)。你需要在N步之内走到目标节点位置上,每走一轮你都要输出你当前点的位置。

    看到这个问题还没读太懂的时候,上去就写了个每次只走一步的代码,结果遇到一个非常长的地图结构那就GG了。

    后来想了一下,告诉方位我们可以每次进行二分查找,并且压缩所在区域的位置啊,也就是

    遇到所有U方位的:说明地图最底部在这个点之上

    遇到所有D方位的:说明地图最顶部在这个点之下

    遇到所有L方位的:说明地图最右侧在这个点左面

    遇到所有R方位的:说明地图最左部在这个点有点

    通过使用二分,将以前的O(n)时间复杂度降到O(logn)级别,基本上可以找到所有点了。

    个人的代码可以给大家伙一个小参考:

    import java.util.*;
    import java.io.*;
    import java.math.*;
    
    /**
     * Auto-generated code below aims at helping you parse
     * the standard input according to the problem statement.
     **/
    class Player {
    
        public static void main(String args[]) {
            Scanner in = new Scanner(System.in);
            int W = in.nextInt(); // width of the building.
            int H = in.nextInt(); // height of the building.
            int N = in.nextInt(); // maximum number of turns before game over.
            int X0 = in.nextInt();
            int Y0 = in.nextInt();
            int u=0,d=H,l=0,r=W;
    
            // game loop
            while (true) {
                String bombDir = in.next(); // the direction of the bombs from batman's current location (U, UR, R, DR, D, DL, L or UL)
    
                // Write an action using System.out.println()
                // To debug: System.err.println("Debug messages...");
               if(bombDir.contains("U")){
                    d=Y0;
                    Y0=((u+Y0)/2);
                }
                if(bombDir.contains("D")){
                    u=Y0+1;
                    Y0=((d+Y0)/2);
                }
                if(bombDir.contains("L")){
                    r=X0;
                    X0=((l+X0)/2);
                }
    
                if(bombDir.contains("R")){
                    l=X0;
                    X0=((r+X0)/2);
                }
    
                // the location of the next window Batman should jump to.
                System.out.println(X0+" "+Y0);
            }
        }
    }
    

    查看测试案例结果为:

    20211104142645

    当然,对于每一个测试案例,你可以滚动滑看其中的测试中间每一轮对应的动画,还是相当nice的。

    image-20211104143011026

    这样自己写的代码能够可视化的看到每一步骤运行在图像上的结果,就像打怪升级一样,有点意思。

    总结

    对于这么一个网站,对初学者编程兴趣的激发还是挺友好的,推荐三两队友一起打怪升级,也可舍友相互比拼,把这个题丢到寝室群里让大伙一块看看,看谁先做对。

    不过任何一个工具都要挑着选着用,可以找一些有挑战但自己可以接受的问题去尝试。玩玩体验一下还是挺有趣的!

    个人公众号:bigsai 欢迎关注

  • 相关阅读:
    文本挖掘预处理之TF-IDF
    文本挖掘预处理之向量化与Hash Trick
    文本挖掘的分词原理
    MCMC(四)Gibbs采样
    MCMC(三)MCMC采样和M-H采样
    编译c时提示“dereferencing type-punned pointer will break strict-aliasing rules”如何处理?
    ubuntu下添加新的ppa软件源后出现"Error: retrieving gpg key timed out"如何处理?
    如何创建离线网页?
    ubuntu下如何安装wpantund?
    tmux如何调节窗口大小?
  • 原文地址:https://www.cnblogs.com/bigsai/p/15541467.html
Copyright © 2011-2022 走看看