0%

本文介绍在linux下实现一个字符小游戏贪吃蛇的过程,游戏纯C++编写,服务器使用chrono定时器做帧同步,支持所有类unix系统的select函数做非阻塞IO,采用TCP socket通信,协议部分采用protobuf二进制流;客户端使用curses字符界面库。

服务器

服务器实现所有逻辑,服务器只接受客户端的操作(包括上下左右四个方向),服务器的几个主要类为server,snake,zone,time分别用于表示一个房间,蛇,战场,计时器。每一局游戏开始,会实例化一个server,监听一个端口,创建一个游戏房间等待玩家接入,这里使用阻塞IOaccept(),需要等加入的玩家达到人数才开始游戏。

就绪后,初始化战场,一个房间对应一局比赛,一个战场。zone类给n个接入的玩家随机分配初始位置。一个战场中包含n个snake信息,snake中存了蛇的长度,以链表结构存储蛇的节点便于头尾的增删。snake中保存蛇的移动方向,当每次用户改变蛇的方向时都会改变方向变量,即使接下来不输入也会继续运动。snake中封装了各种移动方法和判定方法,实现吃事物,死亡,复活等操作。

阅读全文 »

创建一个线程默认的状态是joinable, 如果一个线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收(退出状态码),所以创建线程者应该pthread_join()来等待线程运行结束,并可得到线程的退出代码,回收其资源(类似于wait(),waitpid())

但是调用pthread_join(pthread_id)后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此,比如在Web服务器中当主线程为每个新来的链接创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join()而阻塞(因为还要继续处理之后到来的链接),这时可以在子线程中加入代码pthread_detach(pthread_self()),或者父线程调用pthread_detach(thread_id)(非阻塞,可立即返回),这将该子线程的状态设置为detached,则该线程运行结束后会自动释放所有资源。

阅读全文 »

2022.6 本文对于现在的Raspberry Pi OS已经不适用,移步官方文档

之前尝试了树莓派用作无限AP的教程,大多都只能获得ipv4地址,本文参考一篇教程,可以让树莓派给接入设备分配ipv6地址

原文链接:How to use your Raspberry Pi as a wireless access point

环境:原生Raspbian

安装和更新Raspbian

因为hostapddnsmasq对依赖的版本要求很高,需要先更新系统:

sudo apt-get update
sudo apt-get upgrade

更新后可能依然提示依赖版本过低,所以最好先sudo reboot
阅读全文 »

data.table是对R的原生包data.table的扩展版本,无论是编码效率和执行效率都要比data.table快的多

在本章中:
– subset特指对行的选择
– select特指对列的选择

创建

DT <- data.table(ID = c("b","b","b","a","a","c"), A = 1:6, B = 7:12,C=13:18)

可见data.table的创建和data.frame类似,都是传入若干个向量,不同的是,data.frame中的character类型向量会自动转化为factor,data.table则不会,使用class(DT$ID)查看该属性的类型,返回”character”

也可以根据已有的data.frame类型直接转化为data.table:A是data.frame类型

B <- as.data.table(A)

阅读全文 »

描述性统计分析

统计函数:

对于向量类型x:
| 统计量 | 函数 |
| ——- | ——- |
| 平均数 | mean(x) |
| 中位数 | median(x) |
| 方差 | var(x) |
| 标准差 | sd(x) |
| 值域 | range(x) |
| 求和 | sum(x) |
| 求最小值 | min(x) |
| 求最大值 | max(x) |

阅读全文 »