Bir sayının onun katı mı yoksa belirli bir aralık kümesi içinde mi olduğunu belirleme


104

Programımda ihtiyacım olan birkaç döngüm var. Sözde kodu yazabilirim, ancak bunları mantıksal olarak nasıl yazacağımı tam olarak bilmiyorum.

İhtiyacım var -

if (num is a multiple of 10) { do this }

if (num is within 11-20, 31-40, 51-60, 71-80, 91-100) { do this }
else { do this } //this part is for 1-10, 21-30, 41-50, 61-70, 81-90

Soruma daha mantıklı geliyorsa, bu bir yılan ve merdiven masa oyunu içindir.

Modulus kullanmam gerekecek ilk if ifadesini hayal ediyorum. Misiniz if (num == 100%10)doğru?

İkincisi hiçbir fikrim yok. Şöyle yazabilirim if (num > 10 && num is < 21 || etc.)ama bundan daha akıllıca bir şey olmalı.


16
Genel olarak, iyi kodun uzunluğu, ne yaptığını açıklayan ingilizcenin uzunluğu ile orantılıdır. Yani "spesifikasyonunuz" 11-20, 31-40, 51-60, 71-80, 91-100 dediğinde, kodunuzun bu sayılardan da bahsetmesini bekleyebilirsiniz. Bu numaralar bir yerden geliyorsa veya herhangi bir nedenle oluşturulmuşsa, sayılar yerine nedeni kodlayıp kodlayamayacağınıza bakın.
luqui

39
@ user3419168: Derleyici, kodunuzun ne kadar okunabilir olduğunu hiç umursamıyor; onu bir saniyeden daha kısa sürede derleyecektir. Ancak kodunuzu okuyan insanlar için, yaptığınız seçimler kodun saniyeler, dakikalar, saatler içinde anlaşılmasına veya asla anlaşılmasına neden olabilir. Bu bir maliyet getirir; insanlar kodu okumak ve anlamak için para alıyorlar, bu yüzden işlerini kolaylaştırın. Okunabilirliği en üst düzeye çıkarmak için her zaman üretim kodu yazın ve kesinliğin kodun daha iyi performans göstermesini gerektirmediğini unutmayın.
Eric Lippert

2
@AmadeusDrZaius - ÇOK NADİRDE aynısını yaptım, ancak yalnızca performansın kritik olduğu bölümler için. 100M kez olarak adlandırılan en sıkı döngü, uygun olan bir yılan ve merdiven oyunundaki if ifadesi geçerli değildir. Aralarında bir çizgi çizdiğiniz yer kişisel bir seçimdir.
Floris

2
Bunu söylemekten nefret ediyorum, ancak yeterince kurumsal çalışma yaptıktan sonra, yeni başlayanlar gerçek kod yazarken, onu kaba zorlamayı tavsiye etmem gerekir. Çünkü o zaman yeni çocuklar anlayacak ve kırmayacaktır. üzücü ama gerçek - bazı durumlarda aptal olmak akıllıca.
Richard Le Mesurier

22
Bu doğru bir soru ve posterden hiç bir şey çıkarmak istemiyorum, ancak bu 500+ puanı hak etmiyor. Burada otorite gibi görünen binlerce noktaya sahip insanlarla yaptığımız bazı saçmalıkları bu şekilde sonuçlandırıyoruz. (Başka bir yere aitse bu yorumu taşımaktan çekinmeyin.)
GaTechThomas

Yanıtlar:


87

İlki için, bir sayının çoklu kullanım olup olmadığını kontrol etmek için:

if (num % 10 == 0) // It's divisible by 10

İkincisi için:

if(((num - 1) / 10) % 2 == 1 && num <= 100)

Ancak bu oldukça yoğun ve seçenekleri açıkça listelemeniz daha iyi olabilir.


Artık ne yaptığınız hakkında daha iyi bir fikir verdiğinize göre, ikincisini şu şekilde yazacağım:

   int getRow(int num) {
      return (num - 1) / 10;
   }

   if (getRow(num) % 2 == 0) {
   }

Bu aynı mantık, ancak işlevi kullanarak ne anlama geldiğine dair daha net bir fikir ediniriz.


79
if((num - 1) / 10) % 2 == 1 && num < 100)- Bunu görürsem ağlardım.
Daniel Kamil Kozar

32
@DanielKamilKozar, gerektiği gibi.
Winston Ewert

2
@ user3419168, sadece kendi başına insanı dünyada ne anlama geldiğini merak etmeye bırakıyor. Dünyada ne yapmaya çalıştığına dair hiçbir ipucu vermiyor. Bu yüzden düzenlemede, mantığı bir fonksiyona bölen ve hesaplamaların gerçekte ne yaptığını daha net hale getiren bir versiyon gösterdim.
Winston Ewert

3
Ayrıca num >= 11(1) alt sınırın yasaklandığını ve (2) %negatif bir sayı için de negatif bir sayı döndürdüğünü ileri sürmek akıllıca olabilir . ( & 1Burada kullanmanın "daha güvenli" olduğunu ancak ek bilgi gerektirdiğini kabul etmeliyim .)
usr2564301

2
Düzenleme için +1, aralık listesinin nedenine girer ve okunabilir bir şekilde sunar. IMO'ya göre, bir adım getRow(num) % 2 == 0, amacın ne olduğunu kristal bir şekilde netleştirmek için bir işlevi de sarmak olacaktır . bool inEvenRow(int num){ return getRow(num) % 2 ==0;}
Bay Mindor

40

eğer (sayı 10'un katı ise) {bunu yap}

if (num % 10 == 0) {
  // Do something
}

eğer (sayı 11-20, 31-40, 51-60, 71-80, 91-100 aralığındaysa) {bunu yapın}

Buradaki hile, aralıklar arasında bir tür ortaklık aramaktır. Elbette her zaman "kaba kuvvet" yöntemini kullanabilirsiniz:

if ((num > 10 && num <= 20) ||
    (num > 30 && num <= 40) ||
    (num > 50 && num <= 60) ||
    (num > 70 && num <= 80) ||
    (num > 90 && num <= 100)) {
  // Do something
}

Ama çıkarma eğer fark edebilirsiniz 1gelen num, aralıkları gerekecek:

10-19, 30-39, 50-59, 70-79, 90-99

Başka bir deyişle, ilk basamağı tek olan tüm iki basamaklı sayılar. Sonra, bunu ifade eden bir formül bulmanız gerekiyor. İlk basamağı 10'a bölerek elde edebilirsiniz ve 2'ye böldüğünüzde 1'in kalanını kontrol ederek tuhaf olduğunu test edebilirsiniz. Hepsini bir araya getirerek:

if ((num > 0) && (num <= 100) && (((num - 1) / 10) % 2 == 1)) {
  // Do something
}

Daha uzun ancak bakımı yapılabilir kod ile daha kısa "akıllı" kod arasındaki denge göz önüne alındığında, her seferinde daha uzun ve daha net seçerdim. En azından, zeki olmaya çalışırsanız, lütfen tam olarak neyi başarmaya çalıştığınızı açıklayan bir yorum ekleyin.

Kod üzerinde çalışacak bir sonraki geliştiricinin silahlı olduğunu ve nerede yaşadığınızı bildiğini varsaymak yardımcı olur. :-)


7
Yine de akıllı kodu tercih ederdim, ancak işlevleri çıkararak onu sürdürülebilir koda dönüştürürdüm. Bu son bit && isTensDigitOdd(num), belki de işlev tanımından önce ne yaptığını açıklayan bir yorumla söylense, aynı şekilde okunabilir olacaktır . Böyle bir model mevcutsa, modelin gerekçesini açıklayan bir yorum sürdürülebilirlik imo için aydınlatıcıdır.
chris

3
Chris, "zekâ" nın açık bir avantajı olduğunda bu harika bir stratejidir: çok daha kısa kod (bu, özellikle değişirse daha az yazım hatası şansı anlamına gelir) veya verimlilikte büyük bir gelişme. Kısalık, netlik ve verimlilik arasında neredeyse her zaman bir değiş tokuş vardır ve iyi bir uzlaşma bulmak, geliştirmek için harika bir beceridir. ( Snicker için stackoverflow.com/a/2151844/29157'ye bakın .)
Adam Liss

1
Bu çok daha iyi bir yaklaşım. Anlaşılması 'akıllı kod'dan çok daha kolay ve performans farkı muhtemelen göz ardı edilebilir.
user1477388

@AdamLiss, Evet, bu kararların sonuçlarını görecek kadar deneyimim olmadığı için fikrim çok az değerli. Eminim yakında olacağım ve gerekirse ikinci bir görüş alacağımdan eminim.
chris

1
Kendinizi kısa satmayın. İçgüdüleriniz çok mantıklı ve öğrenmeye devam etmek için istekli görünüyorsunuz. Her fikir, arkasında iyi bir sebep varsa değerlidir ... ve bazen olmasa bile. Çok uzağa gideceğine bahse girerim.
Adam Liss

30

GCC veya vaka aralıklarını destekleyen herhangi bir derleyici kullanıyorsanız bunu yapabilirsiniz, ancak kodunuz taşınabilir olmayacaktır .

switch(num)
{
case 11 ... 20:
case 31 ... 40:
case 51 ... 60:
case 71 ... 80:
case 91 ... 100:
    // Do something
    break;
default:
    // Do something else
    break;
}

1
Lütfen bana bu kodun neden taşınabilir olmadığını söyler misiniz?
M Sharath Hegde

8
@MSharathHegde o standardın bir parçası değildir ve bazı derleyici bunu desteklemeyeceğini GCC uzantısı gerektirdiğinden
Bryan Chen

5
Bu doğru cevap, çünkü niyetin ne olduğu hemen belli oluyor. Modulo ile verilen tüm bu 'akıllı' yanıtlar, yorumlarda bile bir bakım kabusu.
smirkingman

@smirkingman Gerçekten de ana soruya yaptığım yorumda bunu söyledim. Apaçık olan yolun genellikle akıllı ninja yönteminden çok daha iyi olduğunu anlamak için kurumsal bir işte yeni kodlayıcıların deneyimleri yeterlidir.
Richard Le Mesurier

15

Bu, yeni başlayanlardan çok gelecekteki ziyaretçiler için. Daha genel, algoritma benzeri bir çözüm için, başlangıç ​​ve bitiş değerlerinin bir listesini alabilir ve bunlardan birinde geçirilen bir değer olup olmadığını kontrol edebilirsiniz:

template<typename It, typename Elem>
bool in_any_interval(It first, It last, const Elem &val) {
    return std::any_of(first, last, [&val](const auto &p) {
        return p.first <= val && val <= p.second;
    });
}

Basit olması için, açık bir pairargüman yerine polimorfik bir lambda (C ++ 14) kullandım . Bu aynı zamanda muhtemelen kullanarak tutması gerektiğini <ve ==standart algoritmalar ile tutarlı olması için, ancak sürece bu gibi çalışır Elemetti <=bunun için tanımlanmış. Neyse, şu şekilde kullanılabilir:

std::pair<int, int> intervals[]{
    {11, 20}, {31, 40}, {51, 60}, {71, 80}, {91, 100}
};

const int num = 15;
std::cout << in_any_interval(std::begin(intervals), std::end(intervals), num);

Burada canlı bir örnek var .


Düzgün çözüm. Çiftleri temsil etmek için satır başına 2 sayı ile biçimlendirebileceğiniz için muhtemelen tek bir dizi kullanırdım.
Kevin Lam

@ HunterGuy2, Çok iyi bir nokta. Aslında onu çiftler üzerinde çalışacak şekilde değiştireceğim çünkü nedense sadece zip yineleyicileri düşünüyordum.
chris

Gerçekten güzel stl yaklaşımı! Sevdim!
higuaro

5

İlki kolaydır. Modulo operatörünü num değerinize uygulamanız yeterlidir:

if ( ( num % 10 ) == 0)

C ++, 0 olmayan her sayıyı doğru olarak değerlendirdiğinden, şunu da yazabilirsiniz:

if ( ! ( num % 10 ) )  // Does not have a residue when divided by 10

İkincisi için, bunun anlaşılması daha temiz olduğunu düşünüyorum:

Desen her 20'de bir tekrar eder, böylece modulo 20'yi hesaplayabilirsiniz. 20'ye bölünebilenler dışında, istediğiniz tüm elemanlar arka arkaya olacaktır.

Bunları da almak için, negatif sayılarla uğraşmaktan kaçınmak için num-1 veya daha iyisi num + 19 kullanın.

if ( ( ( num + 19 ) % 20 ) > 9 )

Bu, desenin sonsuza kadar tekrar edeceğini varsayıyor, bu nedenle 111-120 için tekrar geçerli olacak ve bu böyle devam edecek. Aksi takdirde sayıları 100 ile sınırlamanız gerekir:

if ( ( ( ( num + 19 ) % 20 ) > 9 ) && ( num <= 100 ) )

5

Koddaki birkaç iyi yorumla, oldukça kısa ve okunaklı bir şekilde yazılabilir.

// Check if it's a multiple of 10
if (num % 10 == 0) { ... }

// Check for whether tens digit is zero or even (1-10, 21-30, ...)
if ((num / 10) % 2 == 0) { ... }
else { ... }

2
İlk yoruma gerek yok. Biraz deneyime sahip herhangi bir programcı, bunun 10'un katları ile num % 10 == 0aynı şey olduğunu bilecektir num.
Justin

7
evet ama yeni başlayanlar da bu siteyi okuyor. Normalde bu yorumu kendi kodumda kullanmazdım, ancak cevabı bu başlangıç ​​sorusundan fayda sağlayacak yeni başlayanlar için daha net hale getiriyor.
La-comadreja

2
Lütfen bunu bir daha yapma. Aslında okuyucuyu yavaşlatarak ve her şeyi iki kez okumaya zorlayarak okunabilirliği azaltır. Bunu anlamayan herhangi bir programcı , kodunuzun bakımını yapmaması gerektiği if (num % 10 == 0)anlamına gelir . Bu iyi bilinen bir anti-modeldir. // Check if it's a multiple of 10
Dawood ibn Kareem

1
@DavidWallace yukarıdaki yoruma bakın. Bu yazının okuyucularının bu anti-kalıbı bileceğini garanti edemeyiz.
La-comadreja

1
Hayır, ne yaptığını söylemek için her satırı yorumlamanın bir anti-model olduğunu kastediyorum. Kullanmanın %bir anti-model olduğunu söylemiyorum ; belli ki öyle değil. Gerçekten, bu yazının okuyucularının çoğunun yeni başlayanlar olacağını varsayarsak, onlara bu tarz yorum yazmayı öğretmek, programcılar olarak gelişimlerine olumsuz bir katkı sağlıyor.
Dawood ibn Kareem

4

Cevabı temelde kendiniz açıkladınız, ama işte her ihtimale karşı kod.

if((x % 10) == 0) {
  // Do this
}
if((x > 10 && x < 21) || (x > 30 && x < 41) || (x > 50 && x < 61) || (x > 70 && x < 81) || (x > 90 && x < 101)) {
  // Do this
}

2
Düzeltin x < 41 x > 50ve parantez koyun.
101010

1
@ 40two, Teknik olarak, operator&&daha yüksek bir önceliğe sahip operator||, bu yüzden sorun değil, ancak GCC'nin yine de bu konuda uyardığından eminim.
chris

18
Eşitsizliği yerine 10 < x < 21olarak temsil etmeyi düşünün . Eşitsizliği matematiksel olarak yazdığınız sırayla okumak daha kolay. 10 < x && x < 21x > 10 && x < 21
Eric Lippert

5
Bu kod oldukça okunamaz ve gerçek mantık hakkında çok az şey söylüyor. Bu cevabı beğenmedim.
Dariusz

3
Bunu olumsuz oyluyorum çünkü sen OP'nin yaptığını tam olarak yanıtladın.
Bruno Ferreira

3

Bunu çok düşünüyor olabilirsin.

if (x % 10)
{
   .. code for 1..9 ..
} else
{
   .. code for 0, 10, 20 etc.
}

İlk satır if (x % 10)çalışır çünkü (a) 10'un katı olan bir değer '0' olarak hesaplanır, diğer sayılar kalanları ile sonuçlanır, (b) an'da 0 değeri ifkabul edilir false, diğer herhangi bir değerdir true.

Düzenle:

Yirmili yaşlarda ileri geri geçiş yapmak için aynı numarayı kullanın. Bu sefer, önemli sayı 10:

if (((x-1)/10) & 1)
{
  .. code for 10, 30, ..
} else
{
   .. code for 20, 40, etc.
}

x/100'dan 9'a kadar 0, 10'dan 19'a kadar herhangi bir sayıyı döndürür 1. Çift veya tek üzerinde test yapmak - bu & 1- size çift mi yoksa tek mi olduğunu söyler. Aralıklarınız gerçekte "11 ila 20" olduğundan, test etmeden önce 1 çıkarın.


1

Okunabilirlik talebi

Halihazırda bazı iyi yanıtlarınız olsa da, kodunuzu gelecekteki okuyucular için daha okunabilir hale getirecek bir programlama tekniği önermek isterim - bu altı ay içinde, bir meslektaşınız bir kod incelemesi gerçekleştirmesini istedi, halefiniz, .. .

Bu, herhangi bir "akıllı" ifadeyi tam olarak (adıyla) ne yaptığını gösteren bir işleve sarmaktır. Performans üzerinde çok küçük bir etki olsa da ("ek yükü çağıran işlevden") bu, böyle bir oyun durumunda gerçekten ihmal edilebilir.

Yol boyunca girdilerinizi dezenfekte edebilirsiniz - örneğin, "geçersiz" değerleri test edin. Böylece, bunun gibi bir kodla karşılaşabilirsiniz - ne kadar daha okunaklı olduğunu gördünüz mü? "Yardımcı işlevler" bir yere gizlenebilir (ana modülde olması gerekmez: ne yaptıkları isimlerinden anlaşılır):

#include <stdio.h>

enum {NO, YES, WINNER};
enum {OUT_OF_RANGE=-1, ODD, EVEN};

int notInRange(int square) {
  return(square < 1 || square > 100)?YES:NO;
}

int isEndOfRow(int square) {
  if (notInRange(square)) return OUT_OF_RANGE;
  if (square == 100) return WINNER; // I am making this up...
  return (square % 10 == 0)? YES:NO;
}

int rowType(unsigned int square) {
  // return 1 if square is in odd row (going to the right)
  // and 0 if square is in even row (going to the left)
  if (notInRange(square)) return OUT_OF_RANGE; // trap this error
  int rowNum = (square - 1) / 10;
  return (rowNum % 2 == 0) ? ODD:EVEN; // return 0 (ODD) for 1-10, 21-30 etc.
                                       // and 1 (EVEN) for 11-20, 31-40, ...
}

int main(void) {
  int a = 12;
  int rt;
  rt = rowType(a); // this replaces your obscure if statement

  // and here is how you handle the possible return values:
  switch(rt) {
  case ODD:
    printf("It is an odd row\n");
    break;
  case EVEN:
    printf("It is an even row\n");
    break;
  case OUT_OF_RANGE:
    printf("It is out of range\n");
    break;
  default:
    printf("Unexpected return value from rowType!\n");
  }

  if(isEndOfRow(10)==YES) printf("10 is at the end of a row\n");
  if(isEndOfRow(100)==WINNER) printf("We have a winner!\n");
}

3
YESVe ile çok ileri gitmeye çalışmıyor NOmu?
rmobis

@Raphael_ - iyi olabilir: Ben sadece bir "örneğin" gösteriyordum. Açıkçası birçok insan doğru / yanlış kullanıyor. Ama (farklı diller farklı kurallara kullandıkları için) hatırlayamıyorum: olmasıdır TRUE, Trueya true? Ve eğer varsa, sıradan C'ye eklemem gereken başlık dosyaları nelerdir? Ben de kendim attım. Olumsuz oy alan bu mu merak ediyorum ...
Floris

1

İlki için:

if (x % 10 == 0)

şunlara uygulanacak:

10, 20, 30, .. 100 .. 1000 ...

İkincisi için:

if (((x-1) / 10) % 2 == 1)

için başvuracak:

11-20, 31-40, 51-60, ..

Temel olarak ilk önce şunu x-1elde ederiz :

10-19, 30-39, 50-59, ..

Sonra bunları 10elde etmek için böleriz :

1, 3, 5, ..

Yani bu sonucun tuhaf olup olmadığını kontrol ediyoruz.


1

Aşağıdakileri deneyebilirsiniz:

// Multiple of 10
if ((num % 10) == 0)
{
   // Do something
}
else if (((num / 10) % 2) != 0)
{
    // 11-20, 31-40, 51-60, 71-80, 91-100
}
 else
{
    // Other case
}

OP sorusunda, 10'un katları için kontrol, aralık kontrolü ile ilgili değildir ve aralık kontrolünde 20, kodunuzla ((20/10)% 2) -> ( 2% 2) -> 0
Serpiton

0

Bu sorunun pek çok cevabı olduğunu biliyorum ama yine de benimkini buraya atacağım ...

Steve McConnell's Code Complete , 2nd Edition'dan alınmıştır: "Stair-Step Erişim Tabloları:

Yine bir başka masa erişimi türü merdiven basamağı yöntemidir. Bu erişim yöntemi, bir dizin yapısı kadar doğrudan değildir, ancak çok fazla veri alanını boşa harcamaz. Şekil 18-5'te gösterilen merdiven basamağı yapılarının genel fikri, bir tablodaki girişlerin, farklı veri noktaları yerine veri aralıkları için geçerli olmasıdır.

Buraya resim açıklamasını girin

Şekil 18-5 Merdiven basamağı yaklaşımı, bir "merdivene" çarptığı seviyeyi belirleyerek her girişi kategorize eder. Vurduğu "adım" kategorisini belirler.

Örneğin, bir not verme programı yazıyorsanız, "B" giriş aralığı yüzde 75 ile yüzde 90 arasında olabilir. İşte bir gün programlamanız gerekebilecek çeşitli notlar:

Buraya resim açıklamasını girin

Merdiven basamağı yöntemini kullanmak için, her aralığın üst ucunu bir tabloya koyarsınız ve ardından her aralığın üst ucuna göre bir skoru kontrol etmek için bir döngü yazarsınız. Puanın bir aralığın üstünü ilk geçtiği noktayı bulduğunuzda, notun ne olduğunu bilirsiniz. Merdiven basamağı tekniğiyle, aralıkların uç noktalarını düzgün bir şekilde ele almak için dikkatli olmalısınız. İşte bu örneğe göre bir grup öğrenciye not atayan Visual Basic kodu:

Buraya resim açıklamasını girin

Bu basit bir örnek olsa da, birden çok öğrenciyi, birden çok not verme şemasını (örneğin, farklı ödevlerde farklı puan seviyeleri için farklı notlar) ve not verme şemasındaki değişiklikleri ele alacak şekilde kolayca genelleştirebilirsiniz. "

Code Complete , 2. Baskı, sayfalar 426 - 428 (Bölüm 18).


neden bunun yanlış soru olduğunu düşünüyorsunuz? OP vakasıyla ilgili bir örnek
vermemiş olmam

0

Diğerlerinin de belirttiği gibi, koşulları daha özlü hale getirmek derlemeyi veya yürütmeyi hızlandırmaz ve okunabilirliğe de yardımcı olmaz.

Oyunun yeni yürümeye başlayan bir çocuk versiyonunu 6 x 6 tahtada veya gelişmiş bir versiyonunu (bütün gece oynayabileceğiniz) 40 x 50 tahtada istediğinize daha sonra karar verirseniz, programınızı daha esnek hale getirmenize yardımcı olabilir. .

Bu yüzden onu şu şekilde kodlardım:

// What is the size of the game board?
#define ROWS            10
#define COLUMNS         10

// The numbers of the squares go from 1 (bottom-left) to (ROWS * COLUMNS)
// (top-left if ROWS is even, or top-right if ROWS is odd)
#define firstSquare     1
#define lastSquare      (ROWS * COLUMNS)
// We haven't started until we roll the die and move onto the first square,
// so there is an imaginary 'square zero'
#define notStarted(num) (num == 0)
// and we only win when we land exactly on the last square
#define finished(num)   (num == lastSquare)
#define overShot(num)   (num > lastSquare)

// We will number our rows from 1 to ROWS, and our columns from 1 to COLUMNS
// (apologies to C fanatics who believe the world should be zero-based, which would
//  have simplified these expressions)
#define getRow(num)   (((num - 1) / COLUMNS) + 1)
#define getCol(num)   (((num - 1) % COLUMNS) + 1)

// What direction are we moving in?
// On rows 1, 3, 5, etc. we go from left to right
#define isLeftToRightRow(num)    ((getRow(num) % 2) == 1)
// On rows 2, 4, 6, etc. we go from right to left
#define isRightToLeftRow(num)    ((getRow(num) % 2) == 0)

// Are we on the last square in the row?
#define isLastInRow(num)    (getCol(num) == COLUMNS)

// And finally we can get onto the code

if (notStarted(mySquare))
{
  // Some code for when we haven't got our piece on the board yet
}
else
{
  if (isLastInRow(mySquare))
  {
    // Some code for when we're on the last square in a row
  }


  if (isRightToLeftRow(mySquare))
  {
    // Some code for when we're travelling from right to left
  }
  else
  {
    // Some code for when we're travelling from left to right
  }
}

Evet, ayrıntılı, ancak oyun tahtasında tam olarak ne olduğunu netleştiriyor.

Bu oyunu bir telefonda veya tablette görüntülenecek şekilde geliştiriyor olsaydım, sabitler yerine SATIRLAR ve SÜTUNLAR değişkenleri yapardım, böylece ekran boyutuna ve yönüne uyacak şekilde dinamik olarak (oyunun başında) ayarlanabilirler.

Ayrıca oyunun ortasında herhangi bir zamanda ekran yönünün değiştirilmesine de izin verirdim - tek yapmanız gereken SATIR ve SÜTUN değerlerini değiştirirken diğer her şeyi (her oyuncunun açık olduğu geçerli kare numarası ve tüm yılanların ve merdivenlerin başlangıç ​​/ bitiş kareleri) değişmedi. O zaman tahtayı güzelce çizmeniz ve animasyonlarınız için kod yazmanız gerekir ( ififadelerinizin amacının bu olduğunu varsayıyorum ) ...


Ayrıca Floris'in cevabını yükselttim - benzer bir sonuca ulaşmanın farklı bir tarzı, cevabımı yazmadan önce görmedim
Laurence Renshaw

2
yerine satır içi işlevi kullanmalısınız#define
Bryan Chen

İşlev benzeri #definekomutlar kullandığınızda , genişletmede göründükleri argümanların etrafına parantez koymak iyi bir uygulamadır . Yani #define finished(num) (num == lastSquare)senin yerine yazmalısın #define finished(num) ((num) == lastSquare). Bunun nedeni, yeterince düşük önceliğe sahip bir operatör içeren bir ifade ile böyle bir talimat kullanırsanız, beklediğiniz cevabı alamayacağınızdır. Bu durumda, fazladan parantez kullanmazsanız, o zaman neredeyse kesinlikle istediğiniz gibi olmayan finished(a & b)genişler (a & b == lastSquare).
Dawood ibn Kareem
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.