文件操作——我的世界建造迷宫

我们先来复习一下文件操作

关键字:

with open(‘file’,’权限’) as f:with open 打开文件:with open可以不用close()方法关闭文件,无论在文件使用中遇到什么问题都能安全的退出,即使发生错误,退出运行时环境时也能安全退出文件并给出报错信息。

file:你要打开文件的路径,注意:路径需要写全包括文件的名字例如:’D:\roborobo\MC_dev\MCDemo\某某某.csv’

权限:在with open中有很多种权限,咱们这里用’r+’这种先读取后写入的权限

下面列举了一些权限有兴趣可以了解一下

r: 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式
rb: 以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。
r+: 打开一个文件用于读写。文件指针将会放在文件的开头。
rb+:以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
w: 打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb: 以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
w+: 打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
wb+:以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在,创建新文件。
a: 打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab: 以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。也就是说,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+: 打开一个文件用于读写。如果该文件已存在,文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+:以二进制格式打开一个文件用于追加。如果该文件已存在,文件指针将会放在文件的结尾。如果该文件不存在,创建新文件用于读写。

as f:重命名为f,这是一个对象(他现在就相当于你要打开的那个文件)

f对象的属性

f.read([size]) 将文件数据作为字符串返回,可选参数size控制读取的字节数
f.readlines([size]) 返回文件中行内容的列表,size参数可选
f.write(str) 将字符串写入文件
f.writelines(strings) 将字符串序列写入文件
f.close() 关闭文件
f.closed 表示文件已经被关闭,否则为Falsefile.mode Access文件打开时使用的访问模式
f.encoding 文件所使用的编码

打开文件逐行读取技巧

1.readline,优点:节省内存,不需要一次性把文件内容放入内存中缺点:速度相对较慢

f = open("ip.txt", "r", encoding="utf-8")
ret = f.readline()
while ret:
    print(ret, end='')
    ret = f.readline()
f.close()

2.readlines,一次性读取所有行,内存消耗过大

f = open("ip.txt", "r", encoding="utf-8")
for line in f.readlines():
    print(line, end="")

3.直接for循环

for line in open("ip.txt", "r", encoding="utf-8"):
    print(line, end="")

4.read,类似readline

f = open("ip.txt", "r", encoding="utf-8")
ret = f.read(5)
while ret:
    print(ret, end='')
    ret = f.read(5)
f.close()

调用read()会一次性读取文件的全部内容,如果文件有10G,内存就爆了,所以,要保险起见,可以反复调用read(size)方法,每次最多读取size个字节的内容。另外,调用readline()可以每次读取一行内容,调用readlines()一次读取所有内容并按行返回list。因此,要根据需要决定怎么调用。

如果文件很小,read()一次性读取最方便;如果不能确定文件大小,反复调用read(size)比较保险;如果是配置文件,用readlines()最方便。

建造迷宫

首先咱们需要将地图文件maze1.csv加入到咱们代码文件所在的位置(mcdemo)

先写出老三件我的世界程序

import mcpi.minecraft as mmc
mc  = mmc.Minecraft.create()
x,y,z = mc.player.getTilePos()

打开文件

with open('maze1.csv','r+') as f:

打开之后我们读取文件,我们可以用类似于3d打印技术的方式来建造迷宫,https://www.bilibili.com/video/BV1bp4y197po/?spm_id_from=333.337.search-card.all.click&vd_source=dc5562180db5a10f6fe630f851ac1aca他是一行一行一层一层建造的

那在这里我们使用readlines()这个方法

文件里面有很多行,我需要让他一行一行的出来让我建造,这里我们可以用for循环遍历出我们读出来的所有数据

with open("maze1.csv","r+") as f:
    for i in f.readlines():

现在这个 i 就是一行的数据了,不过setblock最后参数id是数字类型,我们得到的i里面存的数据是字符串类型,而且还是一整串的,需要分开

with open("maze1.csv","r+") as f:
    for i in f.readlines():
        #!分割.split()
        block = i.split(",")
        for j in block:
#!将分割好的block也遍历,取出单独的“id”
            if j == '1':#!如果文件里读出来的是字符串的'1'那就换成数字1
                j = 1
            else:
                j = 0

换完之后我们就可以放置方块了

with open("maze1.csv","r+") as f:
    for i in f.readlines():
        #!分割.split()
        block = i.split(",")
        for j in block:
#!将分割好的block也遍历,取出单独的“id”
            if j == '1':#!如果文件里读出来的是字符串的'1'那就换成数字1
                j = 1
            else:
                j = 0
     mc.setBlock(x,y,z,j)#!id换成我们转换好的j

现在我们的程序还不能造出整个迷宫,因为咱们都建造在了一个地方,我们的x,y,z没有变化

我们来看一下这张图片

左为x-,右为x+,上为z+下为z-

A-F代表行数

假如我们站在A1的左边,我们自己本身的的坐标是xyz,那么A1的坐标是x+1,y,z

A2的坐标是x+2,y,z …. A10的坐标是x+10,y,z

也就是说,我这一行其余坐标没有变化,只有x从1加到了10.

那我可以设置一个变量a,让他一开始为1,最后到10

import mcpi.minecraft as minecraft
mc = minecraft.Minecraft.create()
x,y,z = mc.player.getTilePos()
a = 0
with open("maze1.csv","r+") as f:
    for i in f.readlines():
        #!分割.split()
        block = i.split(",")
        for j in block:
            a+=1 #!在这里让a每次建造方块之前都+1
            if j == '1':
                j = 1
            else:
                j = 0
            mc.setBlock(x+a,y,z,j)#!这里让x加上a

那我们第一行造完第二行应该从哪里开始造呢?B1!!!那B1的坐标是多少呢?x+1,y,z-1

B2的x+2,y,z-1 ……. B10的x+10,y,z-1,貌似x还是从1到10 加上去。x变成了-1

第三行呢?C1是x+1,y,z-2,那也就是说z是控制行数的,而且x在造完第一行会变成x+10我需要让他变回去

import mcpi.minecraft as minecraft
mc = minecraft.Minecraft.create()
x,y,z = mc.player.getTilePos()
a = b = 0
with open("maze1.csv","r+") as f:
    for i in f.readlines():
        #!分割.split()
        block = i.split(",")
        for j in block:
            a+=1
            if j == '1':
                j = 1
            else:
                j = 0
            mc.setBlock(x+a,y,z,j)
        z-=1 #!每次造完一行,就让z减少1
        a = 0#!每次造完一行,就让a变回0
  • Avatar photo

    宁妄

    一个热爱自然却被困在代码世界的“人”

    Related Posts

    牛马耕地

    时空穿梭

    视频教程:

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注