ทางออกที่ดีที่สุดสำหรับ "ระดับสตริง"?


10

ฉันมีเกมที่สร้างแผนที่ระดับสุ่มในช่วงเริ่มต้นของระดับ ฉันต้องการใช้วิธีการบันทึกและโหลดระดับ

ฉันคิดว่าบางที XML อาจเป็นตัวเลือกที่ดีสำหรับการบันทึกตัวแปรทั้งหมดจากนั้นมันจะง่ายสำหรับฉันที่จะสร้างสิ่งที่สามารถแยกวิเคราะห์ XML นั้นและสร้างระดับที่แน่นอน

แต่ XML อาจเกินความต้องการของฉัน ฉันจำได้ในตอนกลางวันด้วย Sega console ที่ไม่มีความสามารถในการบันทึกเกมของคุณ (ฉันคิดว่าเกม Worms ทำเช่นนั้น) พวกเขาจะให้ตัวละครที่คุณสามารถเขียนลงไปได้ หากคุณต่อยสตริงนั้นในภายหลังมันจะโหลดในระดับที่แน่นอน

"ระดับสตริง" จะเป็นตัวเลือกที่ดีหรือไม่? มันจะเป็นการแปลง "base60" บ้างไหม? ฉันจะใช้สิ่งนี้ได้อย่างไร

คำตอบ:


20

สันนิษฐานว่าสิ่งที่คุณต้องบันทึกคือเมล็ดสุ่มซึ่งโดยทั่วไปเป็นเพียง int คุณสามารถเข้ารหัส int ถึง base64 หากคุณต้องการทำให้ทึบขึ้นอีกเล็กน้อย แต่นั่นอาจไม่จำเป็น


นอกจากนี้คุณยังสามารถสร้างเมล็ดพันธุ์จากคำจริง (อาจจะซื้อเพิ่มตัวละครเพื่อให้ได้เมล็ดพันธุ์ของคุณ) และวิธีการคืนสิ่งที่มีความหมายมากขึ้น คุณจะต้องเก็บคำศัพท์ไว้ในเกมของคุณหรือเรียกคืนมา
Jonathan Fischoff

นั่นเป็นเรื่องปกติ แต่มันก็จะต้องเก็บข้อมูลแบบไดนามิกหากมีการเล่นเกม สตริงจะต้องบันทึกตำแหน่ง / คะแนนของตัวละครเป็นต้นดังนั้นวิธีที่ดีที่สุดในการสร้างสตริงนี้คืออะไร
Adam Harte

ฉันอาจจะใช้ JSON (หรือ XML ถ้าคุณต้องการ) เพื่อทำให้เป็นอันดับโลกและจากนั้น base64-encode สตริงนั้น ไม่แน่ใจว่าทั้งหมดนั้นมีประโยชน์ทำไมไม่เพียง แต่สร้างระบบบันทึก / โหลด GUI ที่มุ่งเน้นมากขึ้นเท่านั้น? ฉันคิดว่านี่เป็นเว็บและคุณไม่ต้องการจัดการกับฝั่งเซิร์ฟเวอร์นี้ อาจดูshygypsy.com/farm/p.cgiสำหรับตัวอย่าง?
coderanger

23

รูปแบบใดก็ตามที่คุณใช้สำหรับเกมบันทึกของคุณเพื่อความดีกรุณาใส่หมายเลขรุ่นไว้คุณจะสามารถโหลดได้ย้อนหลังด้วยการแยกสาขาที่หมายเลขเวอร์ชั่นหรือคุณจะสามารถจดจำการบันทึกที่เก่าเกินไปได้อย่างปลอดภัย เพื่อโหลด

คุณจะเสียใจถ้าคุณไม่


7
+1 ไม่ตอบคำถามจริงๆ แต่สำคัญมาก
Jonathan Fischoff

10

JSON ดี แต่ YAML ดีกว่า :) http://www.yaml.org/และhttp://code.google.com/p/yaml-cpp/สำหรับการปรับใช้ที่ดีกว่าอย่างใดอย่างหนึ่ง

YAML เป็นชุดของ JSON ที่เพิ่มการสนับสนุนสำหรับคุณสมบัติที่ดีบางอย่างโดยเฉพาะอย่างยิ่ง:

  • โหนดไบนารี นี่เป็นสิ่งที่ยอดเยี่ยมสำหรับการจัดลำดับประเภทของข้อมูลที่คุณอาจเกี่ยวข้องกับคำอธิบายระดับ JSON ต้องการให้คุณแปลเป็นรูปแบบกลางที่คุณเลือกเช่น Base64 ก่อนที่จะเขียน / หลังการแยกวิเคราะห์ YAML มี !! binary node type ซึ่งบอกให้ parser ไลบรารี่ทำเพื่อคุณ
  • การอ้างอิงเอกสารภายใน หากวัตถุเดียวกันปรากฏขึ้นสองครั้งในเอกสาร JSON จะเขียนสองครั้งและเมื่อคุณอ่านกลับมาคุณจะได้รับสำเนาสองชุด ตัวปล่อย YAML จำนวนมากสามารถตรวจจับสถานการณ์นี้และแทนที่จะเป็นสำเนาที่สองเอาท์พุทการอ้างอิงถึงครั้งแรกเมื่อสามารถตรวจจับได้เมื่อโหลด
  • ประเภทโหนดที่กำหนดเอง คุณสามารถตั้งค่าสถานะแต่ละแผนที่ในรายการด้วยเช่นผู้เล่น !! ศัตรู !! และอื่น ๆ เพื่อให้ข้อมูลประเภทของคุณมากขึ้นนอกวง
  • YAML รองรับการจัดรูปแบบที่อ่านได้มากขึ้น
  • เนื่องจาก JSON เป็นชุดย่อยของ YAML ผู้อ่าน YAML ส่วนใหญ่จึงไม่มีปัญหาในการอ่านเอกสาร JSON

1
Yaml เจ๋งมากและถ้าคุณหลีกเลี่ยงคุณสมบัติบางอย่างของเซ็ตมันสามารถแปลงเป็น json ได้โดยไม่ยาก
Jethro Larson

3

หากคุณต้องการทำให้เป็นอนุกรมข้อมูลทั้งหมดในเกมฉันจะแนะนำ JSON เป็นรูปแบบไฟล์ของคุณมันเป็นเหตุผลที่ง่ายกว่าการใช้ XML และการสนับสนุนดีมากในหลายภาษา

ฉันใช้ไลบรารีนี้สำหรับ C ++ และใช้งานได้ดีมาก

http://jsoncpp.sourceforge.net/


3

XML เป็นตัวเลือกที่ดีถ้าคุณไม่ได้ถูก จำกัด ด้วยขนาดและรองรับแบบดั้งเดิม (เช่นใน. NET และ Flash) แต่ถ้าคุณต้องการรูปแบบที่บางคุณสามารถสร้างรูปแบบและ parser ของคุณเองได้ค่อนข้างง่าย ปกติฉันใช้ 1 ตัวอักษรเช่น จุลภาคเพื่อคั่นแต่ละวัตถุ ในการถอดรหัสสตริงให้ทำการแยกด้วยเครื่องหมายจุลภาค ตอนนี้แต่ละวัตถุต้องการคุณสมบัติที่แตกต่างดังนั้นแยกสิ่งเหล่านี้ด้วยอักขระที่แตกต่างกันเช่นเซมิโคลอนและใช้อักขระอื่นเพื่อแยกชื่อคุณสมบัติจากคุณสมบัติของทรัพย์สินเช่น ปลายลำไส้ใหญ่ ทั้งหมดนี้สามารถถอดรหัสได้อย่างง่ายดายโดยไม่ต้อง regex เพียงแค่ใช้ string.split นี่คือตัวอย่าง:

id:1;x:5;y:45.2;angle:45,id:28;x:56;y:89;angle:12;health:78

คุณสามารถประหยัดพื้นที่ได้มากขึ้นด้วยการทำให้ชื่อคุณสมบัติมีความยาวไม่เกิน 1 ตัวอักษรเช่น h เพื่อสุขภาพ เช่น.

i:1;x:5;y:45.2;a:45,i:28;x:56;y:89;a:12;h:78

เปรียบเทียบกับทางเลือก JSON:

{"o":[{"i":1, "x":5, "y":45.2, "a":45}, {"i":28, "x":56, "y":89, "a":12, "h":78}]}

นอกจากนี้หากคุณต้องการลดขนาดของตัวเลขคุณสามารถเข้ารหัสได้โดยใช้อักขระ UTF16 ที่พิมพ์ได้เต็มชุด หัวข้อนี้แรงบันดาลใจที่จะถามคำถามไปบนกองมากเกินเท่าใดข้อมูลคุณสามารถแพ็คเป็นหนึ่งในตัวละครบนหน้าจอ คำตอบดูเหมือนจะมีค่ามากกว่า 40,000 ค่าสำหรับจำนวนเต็มถ้าคุณไม่คิดว่าจะมี brail, Kanji และ Chess pieces: ♔♕♖♗♘♙♚♛♜♝♞♟

เพื่อให้ได้ขนาดที่ลดลงคุณสามารถใช้ลำดับการอ่าน / เขียนเพื่อกำหนดว่าค่าใดดังนั้นอักขระสองตัวแรกที่แสดงถึง id สองตำแหน่งถัดไปคือตำแหน่ง x, ถัดไปสอง y และมุมแล้วสุขภาพ เป็นต้นดังนั้น:

F5DGP@%&002DFTK#OP1F

สามารถเก็บข้อมูลเดียวกันทั้งหมดเป็นตัวอย่างอื่น ๆ

กริดไทล์สามารถจัดเก็บเป็นเพียงสตริงที่มีตัวละครแต่ละตัวที่เป็นตัวแทนของประเภทที่แตกต่างกันเช่น:

i789pog5h3kl

ที่ฉันอาจหมายถึงลาวา, 9 หมายถึงหญ้า ฯลฯ


นี่คือสิ่งที่ฉันถาม ฉันพูดถึง XML ในคำถามของฉัน แต่ยังมีคนแนะนำ!
Adam Harte

1
เพิ่ม {} บริเวณนั้นโดยทั่วไปแล้วคุณมี JSON ;-)
coderanger

คุณจะต้องเพิ่มเครื่องหมายคำพูด อาจเป็นสองเท่าของจำนวนอักขระ แต่คุณจะได้รับการซ้อนของวัตถุ
Iain

1

หากคุณกำลังเขียนโปรแกรมใน. Net XML นั้นง่ายมากที่จะไปด้วยเนื่องจากคุณสามารถจัดลำดับ / deserialize คลาสระดับของคุณเข้า / ออกของ XML ด้วยสองบรรทัดและจากนั้นมันทั้งหมดในคลาสที่มีการจัดการดี

แผนที่จะเป็นตัวแปรประเภทแผนที่ที่คุณมีข้อมูลทั้งหมดของคุณโหลดไว้

Dim TheMap As New Map

สมมติว่าคุณมีคลาสแผนที่อยู่แล้วสิ่งนี้จะบันทึกแผนที่ของคุณลงใน XML:

Dim Serializer As New System.Xml.Serialization.XmlSerializer(GetType(TheMap))
Dim Strm As New FileStream("c:\Map.xml", FileMode.Create, FileAccess.Write, FileShare.None)
Serializer.Serialize(Strm, TheMap)
Strm.Close()

นี่จะเป็นการโหลด XML นั้นกลับเข้าไปในคลาสแผนที่ของคุณเพื่อใช้อีกครั้งในรหัส

Dim Reader As New StreamReader("map.xml")
Dim Serializer As New System.Xml.Serialization.XmlSerializer(GetType(TheMap))

TheMap = Serializer.Deserialize(Reader)
Reader.Close()

จากจุดนี้ในไฟล์ XML ของคุณจะถูกโหลดเข้าชั้นเรียนของคุณเพื่อให้ใช้งานง่าย

สำหรับปัญหา "ระดับสตริง" ของคุณสิ่งที่ระบุไว้ก่อนหน้านี้จะใช้งานได้ดีคุณสามารถใช้หมายเลข Seed เป็น "ระดับสตริง" ได้

ไม่เช่นนั้นคุณสามารถสร้างแผนที่ที่ต้องการได้หลายแบบล่วงหน้าและบันทึกไว้ทั้งหมดด้วย "Level String" จากนั้นใช้สิ่งนั้นเพื่อดึงแผนที่ที่เหมาะสม


+1 แม้ว่าฉันจะเกลียด XML - หากภาษามีรูปแบบการจัดลำดับเริ่มต้นที่ดีที่สุดควรพิจารณาก่อนเป็นลำดับแรกโดยเฉพาะอย่างยิ่งหากเป็นรูปแบบเครื่องมืออื่น ๆ ที่สามารถแยกวิเคราะห์ในเชิงทฤษฎี (เช่น XML / JSON / YAML)

0

ฉันจะใช้อุปกรณ์ที่เรียบง่ายstructหรือคล้ายกัน (ขึ้นอยู่กับภาษาของคุณ) เพื่อเก็บสถานะเกมทั้งหมดไว้ในที่ส่วนกลาง หากคุณต้องการการป้องกันของ setters / getters คุณสามารถห่อ struct classในส่วน

หากคุณรู้สึกถึงมันใช้ประโยชน์จากbitfieldsหรือเพียงจัดการบิตเองโดยใช้ตัวดำเนินการระดับบิต

โปรดทราบว่าในบางภาษากฎสำหรับการแพ็ดดิงและการบรรจุอาจซับซ้อนเล็กน้อย - แต่มันอาจไม่สำคัญมากสำหรับกรณีของคุณหากคุณมีการเติมเต็มไบต์หรือสองครั้ง

คุณอาจจะสามารถใช้#pragma(เช่น#pragma pack(1)) หรือ__attribute__เพื่อแพ็คโครงสร้างอย่างใกล้ชิดโดยไม่ต้องเว้นระยะห่าง สิ่งนี้อาจหรืออาจไม่ทำงานขึ้นอยู่กับคอมไพเลอร์และสถาปัตยกรรมเป้าหมายของคุณ

โปรดทราบว่าการใช้บิตฟิลด์และแพ็ค pragmas หรือแอตทริบิวต์สามารถลดความสะดวกในการพกพา ข้ามสถาปัตยกรรมของฮาร์ดแวร์ endianness ของฟิลด์ struct (ลำดับไบต์) อาจเปลี่ยนแปลงได้เช่นกัน ดังนั้นคุณอาจต้องการหลีกเลี่ยงปัญหานี้หากคุณพยายามพกพา

(ตัวอย่างเช่น Pac-Man โครงสร้างนี้อาจประกอบด้วยรหัสแผนที่หรือเมล็ดแผนที่อย่างแน่วแน่ตำแหน่ง Pac-Man x และ y ตำแหน่งผีสี่และ y สี่ตำแหน่งและบิตฟิลด์ขนาดใหญ่สำหรับการมีหรือไม่มีเม็ด 32-64 สิ่งสูงสุดคือ.)

เมื่อคุณมี struct แล้วให้ส่งผ่านไปยังฟังก์ชันxxencode

encode_save( char * outStringBuf, size_t outStringBufSize,
             const SaveStruct * inSaveData, size_t inSaveDataSize )

การเขียนฟังก์ชั่นนี้มีข้อผิดพลาดเล็กน้อย คุณจำเป็นต้องเลื่อนและรวมไบต์ตามความจำเป็นเพื่อให้ได้รับครั้งละ 6 บิตจากนั้นแปลเป็นอักขระที่เหมาะสม ฉันพยายามตามล่าหารหัสของคนอื่นเป็นการส่วนตัวเว้นแต่ฉันจะทำเพื่อ "สนุก" (และฉันอาจต้องการชุดทดสอบสำหรับมัน)

อย่าประมาทพลังของโรงเรียนเก่าstructในที่ที่เหมาะสม เราใช้มันเพื่อเกม GBA และ DS ที่นี่


การจัดลำดับโครงสร้างดิบเป็นแบบพกพาไม่ได้และรหัสใหม่ wrt ที่บอบบางมาก นอกจากจะเป็นขั้นตอนสุดท้ายของการอบข้อมูลสำหรับแพลตฟอร์มที่มีทรัพยากรที่ จำกัด มากมันเป็นการปรับให้เหมาะสมก่อนเวลาอันควร มีเหตุผลที่คุณชอบ 6 บิตถึง 8 หรือไม่? รูปแบบจะไม่สามารถอ่านได้โดยมนุษย์คุณอาจใช้ประโยชน์จากความเร็วและการดีบักของโครงร่างจริง

@ โจ: ฉันพูดถึงว่ามันไม่สามารถพกพาได้และมีข้อกังวลบางอย่างที่อาจเกิดขึ้น คำถามที่ถามมาโดยเฉพาะสำหรับ "สตริงระดับ" ที่มนุษย์อ่านได้เช่นเกมเซก้าเก่าและการแปลงเบส 60 ผ่าน struct ผ่านบางสิ่งบางอย่างเช่น xxencode จะทำเช่นนี้ นี่ไม่จำเป็นต้องเป็นการปรับให้เหมาะสมก่อนกำหนด: โครงสร้างที่เรียบง่ายไม่ใช่บิตแพ็คเป็นวิธีการ "ศูนย์กลาง" ที่ดีในการจัดเก็บบันทึกข้อมูลและอาจลดความซับซ้อนของรหัสส่วนใหญ่ที่โต้ตอบกับข้อมูล ดูบทความล่าสุดของ Noel Llopis เกี่ยวกับโครงสร้างที่ไม่ใช่สมาชิกที่ไม่ใช่สมาชิกและการวางโปรแกรม "Inside out" นี่เป็นเพียงจูบ
39670 leander leander

1
ฉันเห็นด้วยกับวิธีนี้โดยสิ้นเชิง ใช่มันไม่ใช่การพกพาข้ามรุ่นหรือระบบ แต่จากนั้นเกมบันทึกอีกครั้งไม่ใช่ทรัพยากรที่จำเป็นต้องใช้ซ้ำในระหว่างการพัฒนาหรือคัดลอกข้ามแพลตฟอร์ม การแก้ปัญหาได้ยากที่จะมีปัญหากับการอ่าน / เขียนใช้งานทันทีและมันจะทำงานได้ตลอดไป หากความสามารถในการขยายตัวเป็นปัญหาจริงๆให้เพิ่มหมายเลขรุ่นเป็น ybyte / คำแรกและคุณสามารถเปิดใช้งานได้ (แม้ว่าจะทำให้เกิดช่องโหว่ของข้อมูล) มันไม่เหมือน xml ที่จะแก้ไขปัญหาเกี่ยวกับเวอร์ชัน - มีแนวโน้มที่จะมีส่วนร่วมมากกว่าเพียงแค่ตั้งค่า ใช่ฉันใช้งานได้จริง
Kaj

0

XML เป็นสิ่งที่ดีสำหรับเอกสารที่มีโครงสร้างตามอำเภอใจ (องค์ประกอบสามารถปรากฏในระดับที่แตกต่างกันของต้นไม้) หรือการฝังรูปแบบต่างประเทศ (เช่นการใส่ svg ในหน้า xhtml) หากคุณไม่มีข้อกำหนดเหล่านั้นมันเป็นรูปแบบที่ไม่มีประสิทธิภาพจริงๆและบางสิ่งที่ง่ายกว่าเช่น csv หรือ json นั้นเป็นที่นิยมมากกว่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.