เคล็ดลับการตีกอล์ฟใน QBasic


13

คุณมีเคล็ดลับทั่วไปอะไรในการเล่นกอล์ฟใน QBasic ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟโดยทั่วไปซึ่งอย่างน้อยค่อนข้างเฉพาะกับ QBasic (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)

เคล็ดลับที่เกี่ยวกับตัวจำลองQB64ก็ยินดีต้อนรับเช่นกัน มันมีคุณสมบัติพิเศษบางอย่างที่ไม่ได้อยู่ใน Microsoft QBasic


ฉันอยากรู้เกี่ยวกับแรงจูงใจของคุณ ฉันไม่ได้ใช้ QBASIC ตั้งแต่ชั้นเรียนโปรแกรมมิงเกรด 10 น่าอัศจรรย์ที่ฉันบันทึกลงฟลอปปี้ดิสก์โดยตรงได้ถึง 1.44 โดยไม่มีการควบคุมเวอร์ชันใด ๆ และหลีกเลี่ยงความล้มเหลวที่ร้ายแรง
Andrew Brēza

5
@ AndrewBrēzaแรงจูงใจ? เช่นเดียวกับแรงจูงใจของฉันในการเล่นกอล์ฟในภาษาใด ๆ : เพื่อความสนุก! ฉันสนุกกับการเขียนโปรแกรมขนาดเล็กใน QBasic (แม้ว่าฉันจะไม่ต้องการใช้กับสิ่งที่ร้ายแรง) นอกจากนี้ยังมีโบนัสเพิ่มที่มีทั้งเสียงและกราฟิก (ทั้งข้อความและพิกเซล) ที่สร้างขึ้นซึ่งภาษา "จริง" ที่ฉันต้องการ Python ไม่ได้
DLosc

การเขียนเกมกราฟิกใน QBasic นั้นง่ายกว่าในงูใหญ่
Anush

หากใครต้องการลองใช้งานแอปพลิเคชัน QBasic แบบกราฟิกโดยตรงในเบราว์เซอร์พวกเขาสามารถใช้สิ่งนี้: github.com/nfriend/origins-host
mbomb007

คำตอบ:


10

รู้โครงสร้างลูปของคุณ

QBasic มีโครงสร้างการวนลูปหลายFOR ... NEXT, และWHILE ... WEND DO ... LOOPคุณสามารถใช้GOTOหรือ (ในบางสถานการณ์) RUNเพื่อวนซ้ำ

  • FOR ... NEXTค่อนข้างดีในสิ่งที่ทำ แตกต่างจาก Python เกือบจะสั้นกว่าเสมอWHILEหรือGOTOวนซ้ำแม้ในขณะที่มันเล่นน้อยกว่า:

    FOR i=1TO 19STEP 2:?i:NEXT
    i=1:WHILE i<20:?i:i=i+2:WEND
    i=1:9?i:i=i+2:IF i<20GOTO 9
    

    โปรดทราบว่าคุณไม่จำเป็นต้องทำซ้ำชื่อตัวแปรหลังจากNEXTนั้นและคุณสามารถกำจัดช่องว่างระหว่างตัวเลขและคำหลักที่ตามมาส่วนใหญ่ได้

  • WHILE ... WENDดีสำหรับเมื่อคุณมีการวนซ้ำที่อาจต้องดำเนินการ 0 ครั้ง แต่ถ้าคุณรู้ว่าการวนซ้ำจะดำเนินการอย่างน้อยหนึ่งครั้งGOTOอาจมีความยาวหนึ่งไบต์:

    WHILE n>1:n=n\2:WEND
    1n=n\2:IF n>1GOTO 1
    
  • ฉันใช้DO ... LOOPลูปไม่ จำกัดเท่านั้น(ยกเว้นที่RUNสามารถใช้แทนได้) แม้ว่าจะมีจำนวนอักขระเท่ากันโดยไม่มีเงื่อนไขGOTOแต่ก็สามารถอ่านได้ง่ายขึ้น (หมายเหตุว่า "ห่วงอนันต์" สามารถรวมลูปที่คุณแยกออกจากการใช้GOTO.) The DO WHILE/ DO UNTIL/ LOOP WHILE/ LOOP UNTILไวยากรณ์ verbose เกินไป คุณดีกว่าที่จะใช้WHILEหรือGOTOตามความเหมาะสม
  • GOTOคือดังกล่าวข้างต้นวิธีทั่วไปที่สั้นที่สุดในการเขียนลูป do / while ใช้หมายเลขบรรทัดหลักเดียวแทนป้ายกำกับ โปรดทราบว่าเมื่อ a GOTOเป็นสิ่งเดียวในTHENส่วนของIFคำสั่งจะมีซินแท็กซ์ช็อตคัตสองตัวที่มีค่าเท่ากัน:

    IF x>y GOTO 1
    IF x>y THEN 1
    

    GOTOนอกจากนี้ยังสามารถใช้ในการสร้างกระแสการควบคุมที่มีความซับซ้อนมากขึ้น ผู้ที่อ้างถึงสิ่งนี้เรียกว่า "รหัสสปาเก็ตตี้" แต่นี่คือรหัสกอล์ฟ: การอ่านไม่ได้เกือบเป็นคุณธรรม! GOTOความภาคภูมิใจ!

  • RUNมีประโยชน์เมื่อคุณต้องการข้ามไปยังตำแหน่งคงที่ในโปรแกรมและคุณไม่จำเป็นต้องเก็บค่าของตัวแปรใด ๆ RUNด้วยตัวเองจะรีสตาร์ทโปรแกรมจากด้านบน; ด้วยป้ายชื่อหรือหมายเลขบรรทัดมันจะรีสตาร์ทที่บรรทัดนั้น ฉันใช้มันเป็นหลักในการสร้างลูปไร้ขีด จำกัด ไร้รัฐ

5

ใช้ทางลัดสำหรับPRINTและREM

คุณสามารถใช้?แทนPRINTและ'แทนREM(ความคิดเห็น)

'อาจมีประโยชน์เมื่อการรวมหลายภาษากับภาษาที่สนับสนุน'ในฐานะส่วนหนึ่งของ char หรือไวยากรณ์สตริง


5

การทดสอบการแบ่งแยก

ในโปรแกรมที่ต้องการให้คุณทดสอบว่าอีกจำนวนหนึ่งหารด้วยอีกวิธีหนึ่งที่ชัดเจนคือการใช้MOD:

x MOD 3=0

แต่วิธีที่สั้นกว่าคือการใช้การหารจำนวนเต็ม:

x\3=x/3

นั่นคือxint-div 3เท่ากับลอยx div3

โปรดทราบว่าวิธีการทั้งสองนี้จะกลับมาสู่ความ0เท็จและ-1เพื่อความจริงดังนั้นคุณอาจต้องลบล้างผลลัพธ์หรือลบทิ้งแทนที่จะเพิ่ม


หากคุณต้องการสภาพตรงข้าม (เช่นxเป็นไม่ได้หารด้วย3) ซึ่งเป็นวิธีการที่เห็นได้ชัดคือการใช้ที่ไม่เท่ากับผู้ประกอบการ:

x\3<>x/3

แต่ถ้าxรับประกันว่าจะไม่ติดลบเราสามารถบันทึกไบต์ การหารจำนวนเต็มจะตัดทอนผลลัพธ์ดังนั้นมันจะน้อยกว่าหรือเท่ากับการหารแบบลอย ดังนั้นเราสามารถเขียนเงื่อนไขดังนี้

x\3<x/3

ในทำนองเดียวกันหากxรับประกันว่าจะเป็นลบการตัดจะเพิ่มผลลัพธ์และเราสามารถเขียนx\3>x/3ได้ หากคุณไม่ทราบว่าสัญลักษณ์ของคุณจะต้องติดx<>


5

การละเมิดเครื่องสแกน

ในหลายภาษาการรู้ว่าตัวละครตัวไหนสามารถและไม่สามารถลบออกได้เป็นสิ่งสำคัญ

  • ช่องว่างใด ๆ ที่อยู่ติดกับสัญลักษณ์สามารถลบออกได้: IF""=a$THEN?0
  • พื้นที่สามารถจะถูกลบออกระหว่างหลักและตัวอักษรที่เกิดขึ้นในลำดับที่FOR i=1TO 10STEP 2 : มีความแตกต่างบางอย่างระหว่าง QBasic 1.1 (หาได้ที่archive.org ) และQB64 :
    • QBasic 1.1 อนุญาตให้ลบช่องว่างระหว่างตัวเลขและตัวอักษรต่อไปนี้ นอกจากนี้ในงบการพิมพ์ก็จะอนุมานอัฒภาคระหว่างค่าติดต่อกัน: กลายเป็น?123x PRINT 123; xข้อยกเว้นข้างต้นเป็นลำดับเช่น1e2และ1d+3ซึ่งถือว่าเป็นเครื่องหมายทางวิทยาศาสตร์และขยายไปถึง100!และ1000#(ความแม่นยำเดียวและสองครั้งตามลำดับ)
    • QB64 โดยทั่วไปเหมือนกัน แต่ตัวเลขไม่สามารถจะตามมาด้วยd, eหรือfที่ทุกคนจนกว่าพวกเขาจะเป็นส่วนหนึ่งของรูปแบบที่ดีที่แท้จริงทางวิทยาศาสตร์ (ตัวอย่างเช่นคุณไม่สามารถละเว้นพื้นที่หลังจากที่จำนวนบรรทัดใน1 FORหรือ9 ENDเช่นคุณสามารถใน QBasic ที่เหมาะสม.) มันเพียงอนุมานอัฒภาคในงบพิมพ์ถ้าหนึ่งในการแสดงออกเป็นสตริง: ?123"abc"ผลงาน แต่ไม่ได้หรือ?TAB(5)123?123x
  • การพูดของอัฒภาค QBasic 1.1 เพิ่มอัฒภาคต่อท้ายกับPRINTคำสั่งที่ลงท้ายด้วยการเรียกหรือTAB SPC(QB64 ไม่ได้)
  • 0สามารถละเว้นก่อนหรือหลังจุดทศนิยม ( .1หรือ1.) แต่ไม่ใช่ทั้งสอง ( .)
  • ENDIFEND IFเทียบเท่ากับ
  • สามารถตัดเครื่องหมายอัญประกาศคู่ปิดของสตริงที่ท้ายบรรทัด

endifใช้งานได้จริงใน QB64 ดูคำตอบนี้
wastl

@wastl ดังนั้นมันจึงเป็นเช่นนั้น เมื่อฉันทดสอบเป็นครั้งแรกใน QB64 ฉันใช้เวอร์ชันเก่ากว่าซึ่งเป็นข้อผิดพลาดทางไวยากรณ์ ขอบคุณที่พูดถึง!
DLosc

4

รวมNextงบ

Next:Next:Next

อาจจะข้นลงไป

Next k,j,i

ที่ iterators สำหรับForลูปi, jและk- ในลำดับที่

ตัวอย่างด้านล่าง (69 ไบต์)

Input n,m,o
For i=0To n
For j=0To m
For k=0To o
?i;j;k
Next
Next
Next

อาจถูกย่อให้เหลือ 65 ไบต์

Input n,m,o
For i=0To n
For j=0To m
For k=0To o
?i;j;k
Next k,j,i

และเท่าที่สิ่งนี้มีผลกระทบต่อการจัดรูปแบบและการเยื้องฉันคิดว่าวิธีที่ดีที่สุดในการจัดการสิ่งนี้คือการจัดแนวข้อความถัดไปให้ตรงกับคำสั่งด้านนอกมากที่สุด เช่น.

Input n,m,o
For i=0To n
    For j=0To m
        For k=0To o
            ?i;j;k
Next k,j,i

4

รู้วิธีการป้อนข้อมูลของคุณ

QBasic มีหลายวิธีที่จะได้รับการใส่แป้นพิมพ์ของผู้ใช้: INPUT, LINE INPUT, และINPUT$INKEY$

  • INPUTเป็นคำสั่งอินพุตมาตรฐานอเนกประสงค์ของคุณ Enterโปรแกรมหยุดสิ่งที่มันทำแสดงเคอร์เซอร์และช่วยให้ผู้ใช้ประเภทการป้อนข้อมูลบางยกเลิกโดย INPUTสามารถอ่านตัวเลขหรือสตริงและสามารถอ่านได้หลายค่าโดยคั่นด้วยเครื่องหมายจุลภาค คุณสามารถระบุสตริงเป็นพรอมต์คุณสามารถไปกับพรอมต์เครื่องหมายคำถามเริ่มต้นและคุณยังสามารถ (ฉันเพิ่งเรียนรู้ในคืนนี้) ระงับพรอมต์ทั้งหมด ตัวอย่างการร้องขอ:
    • INPUT x$,y
      ใช้? พรอมต์เริ่มต้นและอ่านสตริงและตัวเลขคั่นด้วยเครื่องหมายจุลภาค
    • INPUT"Name";n$
      พร้อมกับName? และอ่านสตริง
    • INPUT"x=",x
      แสดงพร้อมกับx=(ไม่มีเครื่องหมายคำถาม! ให้สังเกตเครื่องหมายจุลภาคในไวยากรณ์) และอ่านตัวเลข
    • INPUT;"",s$
      ไม่แสดงพรอมต์ (ใช้ไวยากรณ์คอมมาข้างต้นด้วยสตริงพรอมต์ว่าง) อ่านสตริงและไม่ย้ายไปยังบรรทัดถัดไปเมื่อผู้ใช้กด Enter (นั่นคือเซมิโคลอนหลังจากINPUTนั้น) ตัวอย่างเช่นถ้าคุณทันทีหลังจากนี้หน้าจอของคุณจะมีลักษณะเช่นPRINT s$User_inputUser_input
  • หนึ่งในข้อเสียเปรียบINPUTคือคุณไม่สามารถอ่านสตริงที่มีเครื่องหมายจุลภาคในนั้นเนื่องจากINPUTใช้เครื่องหมายจุลภาคเป็นตัวคั่นฟิลด์ หากต้องการอ่านบรรทัดเดียวของพล (พิมพ์ ASCII) LINE INPUTตัวอักษรการใช้งาน มันมีตัวเลือกไวยากรณ์เหมือนกันINPUTยกเว้นว่าจะใช้ตัวแปรตัวเดียวซึ่งต้องเป็นตัวแปรสตริง ข้อแตกต่างอื่น ๆ คือLINE INPUTไม่แสดงพรอมต์ตามค่าเริ่มต้น หากคุณต้องการคุณจะต้องระบุอย่างชัดเจน
  • INPUT$(n)ไม่แสดงพรอมต์หรือเคอร์เซอร์ แต่รอจนกระทั่งผู้ใช้ป้อนnอักขระจากนั้นส่งคืนสตริงที่มีอักขระเหล่านั้น ซึ่งแตกต่างจากINPUTหรือLINE INPUTผู้ใช้ไม่จำเป็นต้องกดEnterหลังจากนั้นและในความเป็นจริงEnterสามารถเป็นหนึ่งในตัวละคร (มันจะให้ตัวอักษร ASCII 13 รู้จักภาษาเหมือน C เป็น\r)

    ส่วนใหญ่แล้วสิ่งนี้มีประโยชน์เหมือนINPUT$(1)ปกติในลูป INPUT$เป็นสิ่งที่ดีในโปรแกรมการโต้ตอบที่ keypresses เดียวทำสิ่ง น่าเสียดายที่ใช้งานได้กับคีย์ที่มีรหัส ASCII เท่านั้น สิ่งนี้รวมถึงสิ่งที่ชอบEscและBackspaceไม่ใช่ปุ่มลูกศรInsertและDeleteและอื่น ๆ

  • ซึ่งเป็นที่INKEY$มามันคล้ายกับINPUT$(1)ว่ามันส่งกลับผลลัพธ์ของการกดปุ่มเดียว1แต่แตกต่างกันในที่:

    • INKEY$ จะไม่มีข้อโต้แย้ง
    • ในขณะที่INPUT$(n)หยุดการทำงานจนกว่าผู้ใช้จะเข้าสู่nตัวอักษรINKEY$อย่าหยุดการทำงาน หากผู้ใช้กำลังกดคีย์INKEY$ส่งคืนสตริงที่แทนคีย์นั้น ถ้าไม่มันกลับ""มา ซึ่งหมายความว่าหากคุณต้องการใช้INKEY$เพื่อรับการกดปุ่มครั้งต่อไปคุณจะต้องใส่มันในการวนรอบที่ไม่ว่าง : 2

      k$=""
      WHILE""=k$
      k$=INKEY$
      WEND
      
    • ทั้งINPUT$และINKEY$ส่งคืนอักขระ ASCII สำหรับคีย์ที่สอดคล้องกับอักขระ ASCII (รวมถึงอักขระควบคุมเช่น escape, tab และ backspace) อย่างไรก็ตามINKEY$ยังสามารถจัดการกับคีย์บางอย่างที่ไม่มีรหัส ASCII ได้ สำหรับสิ่งเหล่านี้ (กล่าวถึงไฟล์ช่วยเหลือ) "INKEY $ ส่งคืนสตริง 2 ไบต์ซึ่งประกอบด้วยอักขระ null (ASCII 0) และรหัสสแกนแป้นพิมพ์"

      ชัดเจนเหมือนโคลนไหม นี่คือตัวอย่างบางส่วน หากคุณใช้INKEY$ลูปด้านบนเพื่อจับภาพปุ่มกดของปุ่มลูกศรซ้ายk$จะมีสตริง"␀K"(ที่มีKรหัสสแกน 75) สำหรับลูกศรขวามันคือ"␀M"(77) เลื่อนหน้าลงคือ"␀Q"(81) F5 คือ"␀?"(63)

      ยังคงชัดเจนเหมือนโคลน? ใช่. มันไม่ใช่สิ่งที่เข้าใจง่ายที่สุดในโลก ไฟล์ช่วยเหลือมีตารางรหัสการสแกน แต่ฉันมักจะเขียนโปรแกรมเล็ก ๆ น้อย ๆ เพื่อพิมพ์ผลลัพธ์INKEY$และกดปุ่มเพื่อค้นหาว่าค่าที่เหมาะสมคืออะไร เมื่อคุณรู้ว่าตัวละครตัวใดที่ตรงกับคีย์คุณสามารถใช้RIGHT$(k$,1)และLEN(k$)แยกแยะระหว่างกรณีต่าง ๆ ทั้งหมดที่คุณอาจพบ

    บรรทัดล่าง INKEY$แปลก แต่มันเป็นวิธีเดียวที่จะไปหากโปรแกรมของคุณต้องไม่ใช่การปิดกั้นอินพุตหรือความต้องการที่จะใช้ปุ่มลูกศร


1ไม่รวมShift, Ctrl, Alt, PrntScr, Caps Lock, และที่คล้ายกัน สิ่งเหล่านั้นไม่นับ : ^ P

2WHILE ... WENDสำนวนนี่คือสิ่งที่ผมได้เรียนรู้ในหนังสือ QBasic ของฉัน เพื่อวัตถุประสงค์ในการเล่นกอล์ฟ แต่ห่วงสั้นGOTO


3

LOCATE สามารถทรงพลังจริงๆ

LOCATEคำสั่งช่วยให้คุณสามารถวางได้ทุกที่เคอร์เซอร์บนหน้าจอ (ภายในปกติ 80x40 ขีด จำกัด ของพื้นที่ตัวอักษร) และพิมพ์บางสิ่งบางอย่างที่ตำแหน่งนั้น คำตอบสำหรับความท้าทายนี้แสดงให้เห็นอย่างแท้จริง (และยังรวมกับเคล็ดลับอื่น ๆ อีกมากมายจากหัวข้อนี้)

ความท้าทายขอให้เราแสดงผลอักขระทุกตัวที่ผู้ใช้กดในตารางขนาด 16x6 ด้วยLOCATEสิ่งนี้เป็นเพียงเรื่องของ div และ mod บนรหัส ASCII ( aในรหัสนี้):

LOCATE a\16-1,1+2*(a MOD 16)

จากนั้นพิมพ์อักขระ:

?CHR$(a)

3

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

DIM a AS STRING: a = "example"
a$ = "example"

* โปรดทราบว่านี่จะสร้างชื่อตัวแปรที่แตกต่างกันสองชื่อ

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

a$ = "Definitely a string"
b! = "Error!"

โปรดทราบว่าสิ่งนี้ยังมีไว้สำหรับอาร์เรย์ โดยปกติแล้วอาร์เรย์ถูกกำหนดเป็น:

DIM a(20) AS STRING

แต่อาร์เรย์ก็ไม่จำเป็นต้องเป็นDIMmed:

a$(2) = "QBasic 4 FUN!"

a$ตอนนี้เป็นอาร์เรย์สำหรับสตริงที่มี11สล็อต: จากดัชนี 0 ถึงและรวมถึงดัชนี 10 ซึ่งทำได้เนื่องจาก QBasic มีตัวเลือกที่อนุญาตให้ทำดัชนีทั้งแบบ 0 และแบบ 1 สำหรับอาร์เรย์ ชนิดของอาร์เรย์เริ่มต้นรองรับทั้งสองวิธีนี้

จำอาร์เรย์ยี่สิบช่องที่เราDIMอยู่ข้างบนได้ไหม? ที่จริงแล้วมี 21 ช่องเพราะหลักการเดียวกันนี้ใช้กับทั้งอาร์เรย์ที่มีสีจางและไม่มีสี


ฉันไม่เคยรู้เลยว่าสิ่งนี้ใช้กับอาร์เรย์ด้วย น่าสนใจ
trichoplax

3

ทำให้IFข้อความสั้นลง

IF คำสั่งค่อนข้างแพงและการเล่นกอล์ฟลงสามารถบันทึกจำนวนมากไบต์

พิจารณาสิ่งต่อไปนี้ (ดัดแปลงมาจากคำตอบของ Erik the Outgolfer):

IF RND<.5THEN
x=x-1
a(i)=1
ELSE
y=y-1
a(i)=0
ENDIF

สิ่งแรกที่เราทำได้คือบันทึกENDIFโดยใช้IFคำสั่งแบบบรรทัดเดียว:

IF RND<.5THEN x=x-1:a(i)=1ELSE y=y-1:a(i)=0

ใช้งานได้ตราบใดที่คุณไม่พยายามวางไว้ในบรรทัดเดียวกันกับสิ่งอื่นใด โดยเฉพาะอย่างยิ่งหากคุณมีIFคำสั่งซ้อนกันเพียงหนึ่งในสุดเท่านั้นที่สามารถเป็นหนึ่งเดียว

แต่ในกรณีนี้เราสามารถกำจัดการIFใช้คณิตศาสตร์ได้ทั้งหมด พิจารณาสิ่งที่เราต้องการ:

  • หากRND<.5เป็นจริง ( -1) เราต้องการ:
    • x เพื่อลดลง 1
    • y อยู่เหมือนกัน
    • a(i) กลายเป็น 1
  • มิฉะนั้นถ้าRND<.5เป็นเท็จ ( 0) เราต้องการ:
    • x อยู่เหมือนกัน
    • y เพื่อลดลง 1
    • a(i) เป็น 0

ตอนนี้ถ้าเราบันทึกผลของเงื่อนไขในตัวแปร ( r=RND<.5) เราสามารถคำนวณค่าใหม่ของx, yและa(i):

  • เมื่อrเป็น-1, x=x-1; เมื่อrเป็น,0x=x+0
  • เมื่อrเป็น-1, y=y+0; เมื่อrเป็น,0y=y-1
  • เมื่อrเป็น-1, a(i)=1; เมื่อrเป็น,0a(i)=0

ดังนั้นรหัสสุดท้ายของเราดูเหมือนว่า:

r=RND<.5
x=x+r
y=y-1-r
a(i)=-r

ประหยัดพื้นที่เก็บมากถึง 20 ไบต์ (40%) จากเวอร์ชันดั้งเดิม


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


3

บางครั้งคุณควรหลีกเลี่ยงอาร์เรย์

อาร์เรย์ใน QBasic เมื่อสร้างอินสแตนซ์โดยไม่ต้องDIMมีเพียง 11 ช่อง หากการท้าทายต้องการช่องมากกว่า 11 ช่อง (หรือช่อง N โดยที่ N สามารถใหญ่กว่า 11) ได้คุณควรDIMเลือกอาร์เรย์ นอกจากนี้สมมติว่าเราต้องการเติมข้อมูลอาเรย์นี้ด้วย:

DIM a$(12)
a$(0) = "Value 1"
a$(1) = "Value 2"
...

แม้แต่สนามกอล์ฟก็สามารถใช้พื้นที่ได้มาก ในโอกาสดังกล่าวอาจมีราคาถูกกว่าเป็นไบต์เมื่อต้องการทำสิ่งนี้:

a$ = "value 1value 2"

ที่นี่เราวางทุกอย่างไว้ใน 1 สตริงที่ต่อกัน ต่อมาเราเข้าถึงได้โดยทำดังนี้:

?MID$(a$,i*7,7)

สำหรับวิธีนี้สิ่งสำคัญคือค่าทั้งหมดมีความยาวเท่ากัน นำมูลค่าที่ยาวนานที่สุดและนำส่วนอื่น ๆ ออกทั้งหมด:

a$="one  two  threefour "

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

คุณสามารถดูเทคนิคนี้ในการดำเนินการที่นี่


3

PRINT( ?) มีนิสัยใจคอบ้าง

ตัวเลขถูกพิมพ์ด้วยช่องว่างนำหน้าและต่อท้าย

การพิมพ์จะเพิ่มการแบ่งบรรทัด พฤติกรรมนี้สามารถเปลี่ยนแปลงได้โดยเพิ่มเครื่องหมายจุลภาคที่ท้ายคำสั่งเพื่อแทรกแท็บแทนหรือเซมิโคลอนเพื่อหลีกเลี่ยงการแทรก:

ไม่จำเป็นต้องใช้&หรือ;ระหว่างการดำเนินการที่แตกต่างกันเมื่อพิมพ์เช่น ?1"x"s$จะต้องพิมพ์ตัวเลข1พร้อมช่องว่างแต่ละด้านตัวอักษรxและเนื้อหาของs$

?"foo"
?"bar"
?10
?"foo",
?"bar"
?"foo"; 
?"bar"
?1CHR$(65)
?1" "CHR$(65)
?"A","B

เอาท์พุท

foo
bar
 10
foo           bar
foobar
 1 A
 1  A
A             B

การพิมพ์ linebreak สามารถทำได้เพียงแค่ ?


เฉพาะในการพิมพ์ตัวเลข: ช่องว่างจะถูกพิมพ์ก่อนจำนวนถ้ามันเป็นลบ; มิฉะนั้น-จะมีการพิมพ์เครื่องหมายลบ พื้นที่จะถูกพิมพ์หลังหมายเลข วิธีที่ดีที่สุดที่ฉันค้นพบเพื่อกำจัดช่องว่างเหล่านี้คือ - ไม่PRINT USINGคิดว่าถ้าคุณต้องการที่จะเพิ่มคำตอบนี้หรือถ้ามันควรจะเป็นคำตอบที่แยกต่างหาก
DLosc

2

WRITE อาจมีประโยชน์แทน PRINT

PRINTมักเป็นวิธีที่คุณต้องการแสดงผลเนื่องจากมีความยืดหยุ่นและมี?ทางลัด อย่างไรก็ตามWRITEคำสั่งสามารถช่วยให้คุณประหยัดไบต์ในสถานการณ์ที่เฉพาะเจาะจง:

  • เมื่อแสดงผลสตริงให้WRITEล้อมด้วยเครื่องหมายคำพูดคู่ ( ") หากคุณต้องการเอาต์พุตที่มีเครื่องหมายคำพูดคู่WRITE s$จะสั้นกว่า?CHR$(34);s$;CHR$(34)มาก ดูตัวอย่างเช่นที่รู้จักกันที่สั้นที่สุดควิน QBasic
  • เมื่อส่งออกตัวเลขWRITEอย่าเพิ่มช่องว่างก่อนและหลังเหมือนPRINTทำ WRITE nสั้นกว่า?MID$(STR$(n),2)มาก ดูตัวอย่างเช่นFizzBuzz ใน QB64
  • เมื่อการแสดงผลหลายค่าWRITEแยกพวกเขาด้วยเครื่องหมายจุลภาค: เอาท์พุทWRITE 123,"abc" 123,"abc"ฉันไม่สามารถนึกถึงสถานการณ์ที่สิ่งนี้จะเป็นประโยชน์ แต่นั่นไม่ได้หมายความว่าไม่มี

ข้อ จำกัด ของWRITE:

  • PRINT a;bมีวิธีการหลายค่าการส่งออกไม่เป็นโดยไม่ต้องคั่นเช่นเดียวกับ
  • ไม่มีวิธีใดในการระงับการขึ้นบรรทัดใหม่ในตอนท้ายของเอาต์พุต (คุณอาจสามารถหลีกเลี่ยงปัญหานี้ได้LOCATEแต่มีค่าใช้จ่ายจำนวนมากเป็นไบต์)

1

บางครั้ง QBasic mangles อินพุตไปยังฟังก์ชัน ใช้ผิดวิธี!

มีฟังก์ชั่นสองอย่างที่ทำงานกับตัวอักษรแทนที่จะเป็นสตริง แต่ไม่มีcharประเภทข้อมูลใน QBasic มีเพียงstring ($)ประเภทเท่านั้น ยกตัวอย่างเช่นASC()ฟังก์ชั่นซึ่งจะส่งคืนรหัส ASCII สำหรับอักขระ ถ้าเราจะเข้า

PRINT ASC("lala")

คนแรกเท่านั้นที่lจะได้รับการพิจารณาโดย QBasic ด้วยวิธีนี้เราไม่ต้องกังวลกับการตัดสายลงไปที่ความยาว 1

อีกตัวอย่างหนึ่งมาจากคำถามนี้ที่STRING$()มีการใช้ฟังก์ชันในคำตอบอย่างใดอย่างหนึ่ง

ฟังก์ชัน STRING $ รับสองอาร์กิวเมนต์หมายเลข n และสตริง s $ และสร้างสตริงที่ประกอบด้วยสำเนา n ตัวอักษรตัวแรกของ s $

@DLosc ที่นี่

โปรดทราบว่า QBasic เมื่อเสนอสตริงแบบมัลติถ่านและต้องการถ่านเพียงตัวเดียวจะใช้ตัวอักษรตัวแรกโดยอัตโนมัติและไม่สนใจส่วนที่เหลือ

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