说一下我个人的看法:
我认为人的智能是由三个模块构成的:生成器,否决器,解释器。生成器生成行为,否决器负责判断要不要执行这个行为、并在决定执行后执行。执行后,解释器对行为做出解释。
意识本质是解释器。即,意识并不控制行为,意识只是解释行为,并通过解释来影响生成器与否决器、使得生成器重新提案,从而间接控制行为。
目前人工智能的算法是深度神经网络,它能实现生成器与否决器,但无法实现解释器。我认为解释器需要一种新的算法(我暂时还不知道是什么算法)。
也许解释器算法出现的那一刻,就是真正的强人工智能诞生的那一刻。(强人工智能:即完全类似人的人工智能。)
*参考资料:
1.斯佩里的裂脑人实验:一个裂脑人(左右脑断开的人)左脑看到鸡的图片,右脑看到雪的图片,然后让他选择相关图片。他左脑选择笼子,右脑选择铲子。但被问到为什么选铲子,他回答的不是【扫雪】,不是【我不知道】,而是【为了扫鸡屎】。这是因为语言位于左脑,裂脑人左脑的生成器不知道右脑看到了什么,但解释器不知道【左脑生成器不知道右脑看到了什么】,所以解释器(意识)做出了一个在它看来最合理的解释:【为了扫鸡屎】。
2.梦游者可以完成炒菜、开车等复杂行为,可以睁眼躲避障碍物,但没有意识。可见复杂行为不需要意识参与,意识是解释器而不是生成器,意识在行为之后生效、而不是行为之前。
3.Benjamin libet的自由意志实验:让实验者从两个按钮中选择一个按下,并在实验者面前有一个秒钟,让实验者记住【自己产生意识、决定按下时的时刻】。实验表明:在实验者产生意识的几秒前,大脑中已经产生了一个电信号,该信号让实验者按下某按钮。通过大脑扫描,可以在实验者产生意识之前,就预测实验者会按下哪个按钮。*
1.6:语句
一句话的基本结构是什么?主谓宾?
不。
自然语言中之所以通常是主谓宾结构,是因为自然语言是一维的,动词左右各可以连接一个名词。但真正的语句中,名词可以只有一个,也可以有三个四个。
古人的解决办法是:对于只有一个名词的,创造一个新名词。对于有多个名词的,拆分出多个谓词。
比如,自然数公理【0是自然数】,这句话的严谨描述是【P(0)】,其中P是一个谓词、相当于【是自然数】。这就是一个【只有一个名词的语句】。
注:有的人觉得不严谨,觉得这不是一个语句,觉得【0属于自然数集】这样的描述才是严谨的语句。但是,什么是集合?他可能回答:空集是集合,一个集合可以构造一个幂集,两个集合可以并。但是,你打算如何严谨描述【空集是集合】?你要描述为【空集属于全部集合所构成的集合】吗?你这是循环定义了。只能说【Q(空集)】,此处的Q相当于【是集合】,这就是一个只有一个名词的语句。
三四个名词的语句很常见,比如【画一个宽为5、高为4的红色矩形】,这本质是【画矩形(5,4,红色)】。再比如【我认为你能做到某事】,这本质是【认为能做到(我,你,某事)】,进一步可以写成【P(我,你,某事)】,P是一个新谓词。
1.6.*:总结
一句话的基本结构,是谓语+参数。谓语只有一个,参数可以有任意个。
自然语言是一维的,这导致谓语强行绑定两个参数。不要被自然语言束缚了思维。
文本编辑器很难做。在我看来,难的根源在于光标:无法确定光标目前选择的是什么东西,基于此而需要大量分类讨论。
进一步的根源在于:文本编辑器中的内容是多层的,而不是一层。
因此,当初我制作论坛时,我的想法是:让文本编辑器是一层的。文本编辑器中只能输入普通文本,但是可以给文本加标记,例如:
这里是<b>正文</b>
同时,网页分为左右两侧,左侧输入文本、右侧显示文本的效果。这样,上面那句话就会在右侧显示为【普通的“这里是”与加粗的“正文”】。
然后,发布文章的时候,把原文发到后台。显示文章的时候,把原文数据以HTML格式显示;修改文章时,把原文数据以普通文本格式显示。
(我当时制作论坛的背景是:我有几个网友,我们喜欢写文章交流,但word文档用不习惯、且各个文档之间是割裂的。于是我制作了一个小型论坛、只限我们几个交流。)
(事实上hackertalk的文本编辑器也有bug,比如加粗时如果选中了【一段普通的话】以及【一段加粗的话的部分】,那么就无法像word文档那样正确的处理加粗。)
我猜,hackertalk的文本编辑器逻辑大概是这样的:
如果点击加粗按钮或者代码框按钮:
获取光标的位置。
在光标的两侧加上某标记。(不同按钮标记不同。)
(重新)显示编辑器内容。
定义【显示编辑器内容】:
处理标记,把标记转化为html标记。
把转化后的文本以html格式显示。可编辑。
如果点击发布:
将带标记的文本发到后台。
如果他人访问帖子:
从后台读取带标记的文本。
处理标记后。
以HTML格式显示。不可编辑。
hackertalk的插入图片,逻辑大概是先上传图片到后台、后台返回图片路径,然后编辑器中用img标签、以该路径来显示图片。
数学公式、表格,这个我就不清楚了。我当初也一直想弄数学公式,但是最后放弃了,改为【使用word文档编辑公式,然后截图、在网页中以图片的形式加入文章】。hackertalk对数学公式的需求不高,没必要费大力加入这个功能,因此我猜也许hackertalk使用了某个他人制作的工具、那个工具自带数学公式编辑器。
问题未解决,但原始问题已解决。(问题:本帖标题。原始问题:如何在Unity中让代码创建的输入框能够显示光标。)
考虑到有人可能希望我将解决过程发出来,因此我描述我的解决过程:
我先是意识到Unity源码中应该有对复制粘贴的定义,于是查Unity源码,查到源码位于编辑器安装路径下的Editor/Data/Resources/PackageManager/BuiltInPackages/com.unity.ugui
阅读了源码后,我找到了编辑器菜单栏中InputField的原理,但是依然没找到运行的函数与复制粘贴的函数。
然后,我去谷歌搜索【TMP_InputField missing caret】,没找到满意的文章。(之前已经在百度与CSDN搜了一圈,没搜到有价值的东西。)
我又搜索【create TMP_InputField with code】,找到了这篇文章:https://forum.unity.com/threads/creating-a-complete-tmp-input-field-via-script.625735/
这篇文章中作者遇到了和我一样的问题,解决方式是使用TMP_InputField的OnEnable函数。
但是这是2015年的文章。我在我的编辑器中尝试使用OnEnable,但是它是私有函数、禁止使用。
后来我发现可以对TMP_InputField所在的GameObject使用SetActive函数,它会调用OnEnable。
于是成功解决问题,代码创建的文本框也可以显示光标了。
1.5:定义的技巧——分步定义
1.5.1:找最小值
现在有一串数字:5,7,6,2,9。需要你定义一个动词:排序。这个动词以一串数字为参数,输出这串数字从小到大排序的结果。
你可能没有头绪。
现在我换一个问题:还是这串数字。现在你需要定义一个动词:找最小值。
这个问题就简单了:
先假设第一个数字是最小值。
然后看第二个数字,如果它更小,那么就让第二个数字是最小值;否则,第一个数字就是最小值。
然后看第三个数字……
以此类推,直至看完所有数字。此时的最小值就是真正的最小值。
定义完【找最小值】之后,再看原本的问题:定义排序。此时就不难了:
先找到最小值。把它写在第一位。
然后看剩余数字,找它们的最小值,把它写在第二位。
然后看剩余数字,找它们的最小值……
以此类推。直至看完所有数字。
1.5.2:滚动条
滚动条怎么定义?
你可能没有头绪。
现在我问你:滚动条的本质是什么?
这个问题很简单:
滚动条的本质,就是【一个物体移动,另一个物体会跟着移动】。
现在回到原本的问题:滚动条的定义。此时就不难了:
有一个滚动块,一个滚动区域,一个被滚动区域。
如果滚动块向上移动,那么被滚动区域向下移动。反之亦然。
滚动块只可以上下移动(不可以左右移动)。
1.4:面向过程
1.4.1:构建与解释
编程要求构建,而不是解释。
构建:第一步,创造一个空集。第二步,在空集中加入元素【1】。
解释:有一个集合,这个集合有一个元素:【1】。
1.3中有这样一段话:
生成一个【超高的此人视角消息记录】。
这个消息记录中,此人的消息在右、对方的消息在左。但是没有滚动条。
整个消息记录是一个超高的画布。
这段话应当改为:
生成一个空画布。
在这个画布中添加一些消息。此人的消息被放在右侧、对方的消息被放在左侧。
1.4.2:循环
生成一个空画布。
在这个画布中添加一些消息:
从【公共消息记录】中获取所有消息。
对于每一条消息:如果这条消息属于此人,那么把它放在空画布的右侧。否则放在左侧。
生成一个空画布。
在这个画布中添加一些消息:
从【公共消息记录】中获取所有消息。设一共n条消息。
首先看第一条消息:如果这条消息属于此人,那么把它放在空画布的右侧。否则放在左侧。
然后看第二条消息:如果这条消息属于此人,那么把它放在空画布的右侧。否则放在左侧。
然后看第三条消息:……
以此类推,直到看完n条消息。
生成一个空画布。
在这个画布中添加一些消息:
从【公共消息记录】中获取所有消息。设一共n条消息。
设x=1。
看第x条消息:如果这条消息属于此人,那么把它放在空画布的右侧。否则放在左侧。
如果x小于n,那么x增加1、然后回到上一句话。否则结束。
面向过程,是指【从开始,经过过程,得到结果】。
面向结果,是指【解释结果是什么样的】。
【新画布与公共消息记录中的信息一样】,这是面向结果的描述。
【获取公共消息记录中的信息。先处理第一条,再处理第二条……】,这是面向过程的描述。
1.3:代码逻辑的优美
如何描述QQ中的消息发送界面?
如果点击发送,那么在消息记录的右侧添加一条消息。
如果点击发送,那么让消息记录整体上移,然后在消息记录下方的右侧添加一条消息。
如果点击发送,那么:
消息记录整体上移。
设A=输入框中的内容。
在消息记录下方的右侧添加一条消息,内容为A。
现在还有一个问题:跟你聊天的那个人的消息记录也需要修改。
如果点击发送,那么:
消息记录整体上移。
设A=输入框中的内容。
在消息记录下方的右侧添加一条消息,内容为A。
接收者的消息记录整体上移。
在接收者的消息记录下方的左侧添加一条消息,内容为A。
这样的设计不优美。这个设计可以重构成另一种优美的设计:
有一个【公共消息记录】。
公共消息记录中,所有消息都排列在左侧,而非【一人在左,一人在右】。
显示消息记录时:
第一步,生成一个【超高的此人视角消息记录】。
这个消息记录中,此人的消息在右、对方的消息在左。但是没有滚动条。
整个消息记录是一个超高的画布。
第二步,截取这个【超高的此人视角消息记录】的下方区域,显示在QQ的消息记录窗口中。
如果点击发送:
在【公共消息记录】中添加一条消息。
让双方重新显示消息记录。
有很多种方式,不知道你所指的游戏开发是哪一种。此处我说一种:
第一步:购买电脑,安装网线,连接电源。
第二步:进入浏览器,进入Unity官网,下载UnityHub。在UnityHub中下载Unity编辑器。
第三步:进入浏览器,进入Visual Studio官网,下载Visual Studio(简称VS)。并将Unity与VS绑定。(绑定方法可以百度查到。)
第四步:打开Unity并新建项目工程文件夹,在Unity中新建C#文件,使用VS打开C#文件,在其中写入代码,保存并关闭。
第五步:在Unity中将代码文件拖动到摄像机上。(Unity项目中自带一个虚拟摄像机)
第六步:点击【文件】菜单中的【构筑】,等待一段时间(小型项目大约十秒),你的项目文件夹下就会出现一个exe文件。双击该exe文件即可运行你的代码所创造的游戏。
第七步:进入浏览器,进入SteamWorks官网,注册账号。(在这里发布游戏。注册账号需要交600元押金,并且需要申报税务与银行卡号,需要填大量表单,审核大约需要一周甚至一个月。)
第八步,注册完毕后,在SteamWorks中创建游戏(包括定价、游戏简介、游戏宣传画、游戏文件),并把之前生成的exe文件上传。这样,其他人就可以在steam上看到并购买你的游戏。
第九步,两个月后银行卡中会出现收益,然后每月一次收益。(六月份的收入需要七月末获得。Steam会把钱自动转到你注册账号时预留的银行卡中。)
第十步,每个月去税务局报税交税。Steam会自动扣除美国税务,你还需要在中国交税。需要自己去税务局报税,否则会被视为逃税:一次警告、二次处罚。
注:Steam转账是美元,个人账户每年最多把五万美元转成人民币(最多五万结汇)。如果你年收入超过五万美元,那么需要注册公司,公司账户结汇无限制。
税务问题很复杂,美国10%、Steam平台30%,这两个是固定的。剩余的国内税务,如果你操作好、那么可以以稿酬收入计算,16%税;但如果操作不好,那么最坏的结果是公司税25%加个人税45%。(操作更好的话甚至可以合法做到0税务,但那属于钻法律漏洞。)
有很多种开发方式。此处我说一种:
第一步,购买电脑,安装网线,启动电源。
第二步,打开百度,搜索阿里云,进入官网,租用云服务器,根据官方教程来配置系统并启动云服务器。(大约一个小时。最简单的服务器每年一百元。)
第三步,远程连接云服务器,在云服务器上下载PHPStudy,在PHPStudy上以云服务器IP地址为名、建立网站。PHPStudy会自动创建一个文件夹。(大约半个小时)
第四步,在文件夹中新建记事本文件,书写html代码(包括CSS与JS与PHP),保存为html格式。
假设你的云服务器IP为205.60.81.247,假设你的文件名为01.html,那么其他电脑上访问【http://205.60.81.247/01.html】即可看到你的html文件所呈现的网页。
注意:
1.如果要使用【.com】之类的域名,那么需要购买并解析。普通域名大约五十元每年。可以在阿里云解析。
2.如果在PHPStudy文件夹下新建文件夹【测试】,并在【测试】中创建【01.html】,那么外界以【http://205.60.81.247/测试/01.html】访问该页面。
3.如果只是搭建网站,那么可以不使用云服务器,而是云虚拟主机。云虚拟主机更便宜。
4.如果不想使用云、而是使用本机,那么需要你的本机拥有固定的公网IP地址。一般家庭主机的公网IP地址是不固定的,需要去营业厅申请固定IP专线,费用大约一万元。
1.2:名词的定义
定义,是【当你想要实现功能X、这需要引入一个概念Y;但计算机中没有概念Y】时,你来定义Y。
例如,当你想说【向集合A中添加一个元素】的时候,你发现计算机中没有集合,只有【低级集合】:这个低级集合的元素数量是固定的,无法改变。
此时,你需要定义【集合】:
定义集合:
定义属性【本体(类型为低级集合)】
定义属性【元素数量(类型为数字)】
定义动词【创建集合】,无参数:本体是一个空的低级集合,元素数量是0。
定义动词【添加元素】,参数为元素X:
创建一个新的低级集合,元素数量是“自身的元素数量+1”。
把本体的元素挨个复制到新的低级集合中。
把新的低级集合的最后一个元素设置为X。
抛弃旧的本体。把这个新的低级集合作为本体。
这样你就可以创建集合并添加元素了。
1.2.*:问答
问:名词的【属性】是什么东西?
答:假设有A与B两个集合。AB不同,为什么他们都叫集合?因为AB的不同只在于【本体】不同或【元素数量】不同。一个名词的有些东西是可以变的。那些可以变的东西就被称为属性。